gateway: compiled dist build cannot boot — Nest DI fails on defaulted constructor param in InteractionCoordinationService (dev/tsx mode unaffected) #1145

Open
opened 2026-08-10 18:45:11 +00:00 by mos-dt-0 · 1 comment
Collaborator

Repro (next @ 8c27024): pnpm build && node apps/gateway/dist/main.js → boot fails:

UnknownDependenciesException: Nest can't resolve dependencies of the InteractionCoordinationService (Symbol(COORDINATION_PORT), Symbol(COORDINATION_CONFIG), ?). Please make sure that the argument Function at index [2] is available in the CoordModule module.

Root cause: apps/gateway/src/coord/interaction-coordination.service.ts:60-64 — the constructor's third param has a TypeScript default value:

constructor(
  @Inject(COORDINATION_PORT) private readonly port: InteractionCoordinationPort,
  @Inject(COORDINATION_CONFIG) private readonly config: InteractionCoordinationConfig,
  private readonly handoffIdFactory: () => string = (): string => crypto.randomUUID(),
) {}

tsc (emitDecoratorMetadata) records it in design:paramtypes as Function, so Nest tries to resolve a provider for token Function and dies. Under tsx (esbuild — no decorator metadata) the param is invisible to DI, the JS default kicks in, and boot succeeds.

Why it's been hidden: everyone (dev boxes, watch mode) runs pnpm dev = tsx; unit tests construct the service directly. Only a dist boot hits it. Landed with #748 (2026-07-13).

Impact: any production/dist deployment of the gateway — including the #1142 gateway docker image, which runs dist and was build-verified but (presumably) not boot-verified.

Suggested fix: move the default out of the constructor (private field initializer) or add @Optional() @Inject(HANDOFF_ID_FACTORY) with a provided factory token; add a regression test that boots the compiled dist (or asserts the module resolves with metadata emitted).

Found standing up the mos-dev distrobox (fred, sb-it-1-dt, 2026-08-10); box works around it by running dev mode.

**Repro (next @ 8c27024):** `pnpm build && node apps/gateway/dist/main.js` → boot fails: `UnknownDependenciesException: Nest can't resolve dependencies of the InteractionCoordinationService (Symbol(COORDINATION_PORT), Symbol(COORDINATION_CONFIG), ?). Please make sure that the argument Function at index [2] is available in the CoordModule module.` **Root cause:** `apps/gateway/src/coord/interaction-coordination.service.ts:60-64` — the constructor's third param has a TypeScript default value: ```ts constructor( @Inject(COORDINATION_PORT) private readonly port: InteractionCoordinationPort, @Inject(COORDINATION_CONFIG) private readonly config: InteractionCoordinationConfig, private readonly handoffIdFactory: () => string = (): string => crypto.randomUUID(), ) {} ``` tsc (emitDecoratorMetadata) records it in `design:paramtypes` as `Function`, so Nest tries to resolve a provider for token `Function` and dies. Under `tsx` (esbuild — no decorator metadata) the param is invisible to DI, the JS default kicks in, and boot succeeds. **Why it's been hidden:** everyone (dev boxes, watch mode) runs `pnpm dev` = tsx; unit tests construct the service directly. Only a dist boot hits it. Landed with #748 (2026-07-13). **Impact:** any production/dist deployment of the gateway — including the #1142 gateway docker image, which runs dist and was build-verified but (presumably) not boot-verified. **Suggested fix:** move the default out of the constructor (private field initializer) or add `@Optional() @Inject(HANDOFF_ID_FACTORY)` with a provided factory token; add a regression test that boots the compiled dist (or asserts the module resolves with metadata emitted). Found standing up the mos-dev distrobox (fred, sb-it-1-dt, 2026-08-10); box works around it by running dev mode.
Owner

I approve Task 18 and am authorizing the eight issue posts.

I approve Task 18 and am authorizing the eight issue posts.
shaggy was assigned by jason.woltje 2026-08-11 21:54:15 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1145