You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TMS: API with DISABLE_EMBEDDED_WORKERS=true delivers no domain events to any handler #327
PgBossEventBus.publish records each event in DomainEventLog, then sends it only to queues for handlers registered in the same process (fanOut walks its local registry). When the API runs with DISABLE_EMBEDDED_WORKERS=true, the documented setup for a separate worker container (docs/SELF_HOSTING.md), index.ts never calls registerEventHandlers. So the API's registry is empty, and every event its commands publish is recorded and delivered nowhere.
In that setup, nothing done through the API reaches:
projections: shipment/order read models, list views, timeline
The standalone worker can't pick them up either, because nothing is ever put on the evt.* queues.
The default docker-compose.yml doesn't set the flag, so the API still runs its own handlers there and isn't affected. Any deployment that follows the separate-worker docs is affected.
Suggested fix
Make fan-out independent of who consumes. The API needs to know every handler's queue name and patterns without consuming from them. For example, registerEventHandlers could register routing for each handler on every process, with eventBus.start() (which subscribes to queues) only called where handlers should run. An alternative is a static routing table built from the handler list.
Acceptance criteria
With DISABLE_EMBEDDED_WORKERS=true on the API and a WORKER_MODE=all worker, creating a shipment through the API updates ShipmentReadModel and the timeline.
No handler runs twice when the API has embedded workers enabled.
A test covers fan-out from a process that registers routing but doesn't consume.
Related gap found while doing #328: handlers that dispatch commands aren't registered in two setups.
Embedded workers (API process, the default dev setup): index.ts calls registerEventHandlers without a command bus, so every handler under if (commandBus) in events/registerHandlers.ts is skipped. That includes IssueEngineHandler and AutoReplenishmentHandler, and the triage agent even with an LLM configured.
Standalone worker:worker.ts only builds its command bus when an LLM provider is configured and enabled, so without one the same handlers are skipped there too.
#336 works around it for route planning only (registerShipmentRoutePlanning, called from index.ts with the container's command bus). The general fix probably belongs with this issue's rework of handler registration: always pass a command bus, in both processes.
Activity
Connor-Finn commentedon Oct 4, 2026
Related gap found while doing #328: handlers that dispatch commands aren't registered in two setups.
index.tscallsregisterEventHandlerswithout a command bus, so every handler underif (commandBus)inevents/registerHandlers.tsis skipped. That includesIssueEngineHandlerandAutoReplenishmentHandler, and the triage agent even with an LLM configured.worker.tsonly builds its command bus when an LLM provider is configured and enabled, so without one the same handlers are skipped there too.#336 works around it for route planning only (
registerShipmentRoutePlanning, called fromindex.tswith the container's command bus). The general fix probably belongs with this issue's rework of handler registration: always pass a command bus, in both processes.Deliver events to handlers in every deployment (#327) (#339)