Skip to content

fix(admin): widen onMessagePublishedEffect runtime to include schema DecodingServices - #124

Open
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-admin-widen-onmessagepublishedeffect-runtime-t-203ca7
Open

detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-admin-widen-onmessagepublishedeffect-runtime-t-203ca7

Conversation

@detail-app

@detail-app detail-app Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Closes #105

Bug

onMessagePublishedEffect's schema-bearing options type MessagePublishedEffectOptionsWithSchema<R, S> extended MessagePublishedEffectOptions<R> without widening R to include the schema's DecodingServices (S['DecodingServices']). Every other background trigger-with-schema wrapper — onTaskDispatchedEffect and the four Firestore triggers onDocumentCreated/Updated/Deleted/WrittenEffect — widens the runtime contract to R | S['DecodingServices'], so a schema whose decoding requires a Context service can't be paired with a runtime that omits it. onMessagePublishedEffect was the lone exception: a messageSchema with non-never DecodingServices type-checked against an insufficient runtime, then at runtime decoding died on the missing service, the wrapper logged Defect in onMessagePublished, and the message was ACKed unprocessed.

Fix

Widen the options type to match the sibling background triggers (one line in packages/admin/src/lib/functions/on-message-published.ts):

interface MessagePublishedEffectOptionsWithSchema<
  R,
  S extends Schema.Top,
> extends MessagePublishedEffectOptions<R | S['DecodingServices']> {
  messageSchema: S;
}

The implementation cast (as Effect.Effect<void, never, R> at line 121) is unchanged, mirroring on-task-dispatched.ts:106 — the implementation signature only binds R, so S isn't in scope there, and the overload options type is the public contract callers are checked against. Schemas with DecodingServices = never (the common Schema.Struct case, plus the in-repo transformEffect schemas that only use Effect.succeed/Effect.fail) are unaffected: R | never === R.

Testing

  • New regression tests in on-message-published.spec.ts: a service-bound messageSchema (a Schema.String.decodeTo whose transformEffect reads a DecoderService Context service) is paired with both a sufficient and an insufficient runtime. A @ts-expect-error on the insufficient-runtime call asserts the compile-time rejection; a runtime test publishes a message through the sufficient runtime and asserts the handler receives the decoded (DecoderService.transform-applied) value.
  • The @ts-expect-error guard was bisimulation-checked: reverting the fix turns the directive into TS2578: Unused '@ts-expect-error' directive (the buggy code compiles cleanly); removing the directive with the fix applied surfaces TS2769: No overload matches this callManagedRuntime<never, never> is not assignable to Runtime<DecoderService> — the same error shape the sibling onTaskDispatchedEffect produces.
  • Sibling parity confirmed: the existing widening in on-task-dispatched.ts and the four Firestore triggers still rejects the identical insufficient-runtime setup; the fix doesn't touch them.
  • Verified the widening is structural to the wrapper (not an artifact of one schema combinator) via a composite Schema.Struct({ userId: <service-bound leaf> }), which inherits the service requirement through Struct.DecodingServices<Fields> and produces the same compile-time rejection.
  • No-schema overload unaffected: calls without messageSchema still resolve to the second overload (MessagePublishedEffectOptions<R>, no widening).
  • Routine checks all pass: typecheck, the admin unit-test suite (8 files / 72 tests, including the 5 in this spec), nx run @effect-firebase/admin:build, eslint, and prettier. The CI gate nx affected -t lint test build succeeds for the affected projects.

Automatic Fixes PRs can be configured here.

@detail-app
detail-app Bot requested a review from fwal as a code owner September 19, 2026 03:42
@github-actions github-actions Bot added 🐛 fix Something is broken or doesn't work properly 📦 admin labels Sep 19, 2026
@greptile-apps

greptile-apps Bot commented Sep 19, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the focused type correction matches existing wrapper patterns and is covered by positive and negative regression cases.

Summary

This PR corrects the schema-aware Pub/Sub wrapper’s public runtime contract so it includes services required during schema decoding.

  • Widens MessagePublishedEffectOptionsWithSchema to require R | S['DecodingServices'].
  • Adds a type-level regression check rejecting a runtime that omits a schema decoding service.
  • Adds runtime coverage showing service-dependent decoding reaches the handler with the transformed value.

Reviews (1) · Last reviewed commit: "fix(admin): widen onMessagePublishedEffe..."

@fwal fwal added this to the 1.0 milestone Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📦 admin 🐛 fix Something is broken or doesn't work properly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] Pub/Sub: onMessagePublishedEffect accepts runtimes missing schema decoding services (type safety gap vs other triggers)

1 participant