No per-run hold: an unrunnable parked run kills the process via an out-of-band `ReplayDivergenceError` (world-postgres 4.3.4 / core 4.8.4)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 365
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 169
Description
On workflow 4.8.4, @workflow/core 4.8.4, @workflow/world-postgres 4.3.4, @workflow/world 4.4.0, @workflow/errors 4.2.1, a non-terminal run whose workflow is not registered in the current deployment is re-enqueued by start()'s reenqueueActiveRuns. The replay raises WorkflowNotRegisteredError, which runtime.js correctly catches and turns into run_failed. Afterwards, EventsConsumer's deferred unconsumed-event check (handleUnconsumed → setTimeout → onUnconsumedEvent) rejects workflowDiscontinuation with a ReplayDivergenceError — but the invocation has already settled, so nothing is racing that promise and the rejection escapes as a process-level unhandledRejection on a timer tick. Any crash-only supervisor then takes the whole process down for one bad run. We can reproduce this reliably by building an image that drops one workflow export. Two things are missing and either would close it: (a) a per-run hold on the World contract — WorkflowRunStatusSchema is pending|running|completed|failed|cancelled with no held state, Storage.runs is read-only, and events.create only advances or terminates a run, so an embedder has no way to say "leave this one for an operator"; and (b) suppressing or routing the deferred divergence rejection once the invocation has settled — or surfacing it through a hook that carries the runId (it carries only eventId today), so an embedder can log and mark the one run instead of losing the process.
Filed from an embedder of the Workflow DevKit (a Postgres World, Node runtime). Happy to provide a minimal reproduction image on request.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure by building an image that omits one workflow export, then inspect runtime.js and EventsConsumer, especially handleUnconsumed, setTimeout, and onUnconsumedEvent. Also read WorkflowRunStatusSchema, Storage.runs, and events.create to understand the available run-state controls. Done means the parked run can be isolated or held without an out-of-band rejection causing an unhandled process-level failure, with the runId available if an embedder must handle it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, postgresql, typescript
- Domain
- backend, databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100