workflow
5.2.3 · 20 Oct 2026Apache-2.01.1M / weekRepositorynpmAtom feed
Latest releases
All 56 releases- 5.x · latest line
5.2.3
20 Oct 2026- security
@pranaygp - Security: remove the
nanoiddependency (pinned at 5.1.6, affected by GHSA-28wg-ghj8-5hjv). Default hook tokens now come from a built-in copy of the same generator, so tokens and seeded random values stay identical for runs recorded on earlier versions. Upgradingnanoiditself would have changed them, becausenanoid@5.1.16draws a different number of random bytes per id. @pranaygp - Resolve a run's encryption key from metadata only, so
Run#getReadable()and resuming a hook stored without a resume context no longer make the server resolve the run's whole input and output first.@VaguelySerious - Fix cross-deployment
start()to 4.x deployments being misread as a run invocation, and keep replayed runs in the original run's region.
@workflow/core@5.2.3
- security
@pranaygp - Security: remove the
nanoiddependency (pinned at 5.1.6, affected by GHSA-28wg-ghj8-5hjv). Default hook tokens now come from a built-in copy of the same generator, so tokens and seeded random values stay identical for runs recorded on earlier versions. Upgradingnanoiditself would have changed them, becausenanoid@5.1.16draws a different number of random bytes per id. @pranaygp - Resolve a run's encryption key from metadata only, so
Run#getReadable()and resuming a hook stored without a resume context no longer make the server resolve the run's whole input and output first.@VaguelySerious - Fix cross-deployment
start()to 4.x deployments being misread as a run invocation, and keep replayed runs in the original run's region.@TooTallNate - Stamp the default snapshot threshold into QuickJS runs at
start()so they qualify for the event limit exemption, warn when a run approaches the event limit, and recommendWORKFLOW_VM=quickjsinMAX_EVENTS_EXCEEDEDandREPLAY_TIMEOUTerrors@VaguelySerious - Read event logs where a step's creation is recorded on its
step_startedalone, with no separatestep_created.@TooTallNate - Preserve
workflowVmandsnapshotThresholdfromexecutionContextinhydrateResourceIOfor observability UIs@karthikscale3 - Avoid redundant history reads when independent hooks register concurrently. Keep existing single-event requests parallel and reconcile their committed events together before continuing, with the normal history reload when the responses do not cover a complete consecutive suffix.
@VaguelySerious - Ignore events a step or hook writes after its outcome during replay instead of failing the run
@workflow/cli@5.0.6
@pranaygp - Resolve a run's encryption key from metadata only when decrypting in
workflow inspect --decryptand the web UI, instead of making the server resolve the run's whole input and output for each lookup.
@workflow/world@5.0.5
@VaguelySerious - Fix cross-deployment
start()to 4.x deployments being misread as a run invocation, and keep replayed runs in the original run's region.@TooTallNate - Exempt QuickJS runs with a positive snapshot threshold from the default per-run event limit, matching the Vercel World
@karthikscale3 - Avoid redundant history reads when independent hooks register concurrently. Keep existing single-event requests parallel and reconcile their committed events together before continuing, with the normal history reload when the responses do not cover a complete consecutive suffix.
@workflow/world-local@5.1.2
@NishitaSikka - Restore missing
run_createdevents for interrupted local run creation.@TooTallNate - Exempt QuickJS runs with a positive snapshot threshold from the default per-run event limit, matching the Vercel World
@AndrewBarba - Fix an edge case in
createHook({ experimental_force: true })where a racingresumeHookcould be dropped during the handover
@workflow/world-postgres@5.0.5
@VaguelySerious - Write
run_started,run_completed,run_failed,run_cancelled,attr_set,step_retrying,wait_createdandwait_completedin one transaction with the entity change they record. A process that died between the two used to leave an entity in a state its event log did not explain; a completed wait with nowait_completedmade the run retry the wait forever. A wait left in that state by an earlier version now gets its missing event on the next attempt.@dretanacr - Write a step's
step_completedorstep_failedrow update and its event in one transaction, asstep_startedalready does. A process that died between the two used to leave a terminal step with no terminal event, so the replayedstep_startedwas refused as terminal and the run never advanced.@pranaygp - Keep a checked-out client in the World's own
pgpool from ending the process when the database drops its connection.@pranaygp - Store timestamps as
timestamp with time zonesocreatedAtis correct when the Postgres server or session is not in UTC. Migration 0027 converts the columns and repairscreated_atvalues written by earlier versions.
@workflow/world-vercel@5.2.3
@VaguelySerious - Fix cross-deployment
start()to 4.x deployments being misread as a run invocation, and keep replayed runs in the original run's region.@karthikscale3 - Avoid redundant history reads when independent hooks register concurrently. Keep existing single-event requests parallel and reconcile their committed events together before continuing, with the normal history reload when the responses do not cover a complete consecutive suffix.
@workflow/web@5.0.6
@pranaygp - Resolve a run's encryption key from metadata only when decrypting in
workflow inspect --decryptand the web UI, instead of making the server resolve the run's whole input and output for each lookup.@TooTallNate - Recommend the QuickJS VM with snapshotting on runs that failed with
MAX_EVENTS_EXCEEDEDorREPLAY_TIMEOUT
@workflow/web-shared@5.0.6
@VaguelySerious - Read event logs where a step's creation is recorded on its
step_startedalone, with no separatestep_created.@TooTallNate - Add
getRunLimitGuidance()for runs that failed withMAX_EVENTS_EXCEEDEDorREPLAY_TIMEOUT, and show the run's workflow VM in the sidebar@VaguelySerious - Ignore events a step or hook writes after its outcome during replay instead of failing the run
@workflow/errors@5.0.5
@TooTallNate - Add a QuickJS snapshotting hint and docs link to
MaxEventsExceededError
5.2.2
13 Oct 2026@pranaygp - Order
setAttributes()resolution with the replay delivery barriers so a branch awaiting it can no longer resume out of event-log order, which could fail the run withREPLAY_DIVERGENCEor hand concurrent branches each other's step results@http-samc - Upgrade devalue to 6.0.3, which escapes large strings with native
JSON.stringifyinstead of a per-character loop. Strings containing unpaired surrogates now round-trip exactly instead of being replaced with U+FFFD.@VaguelySerious - Remove the experimental
WORKFLOW_RESILIENT_STEP_DISPATCHoption
@workflow/core@5.2.2
@pranaygp - Order
setAttributes()resolution with the replay delivery barriers so a branch awaiting it can no longer resume out of event-log order, which could fail the run withREPLAY_DIVERGENCEor hand concurrent branches each other's step results@http-samc - Upgrade devalue to 6.0.3, which escapes large strings with native
JSON.stringifyinstead of a per-character loop. Strings containing unpaired surrogates now round-trip exactly instead of being replaced with U+FFFD.@VaguelySerious - Remove the experimental
WORKFLOW_RESILIENT_STEP_DISPATCHoption
@workflow/world-vercel@5.2.2
@mmarufov - Fix
UND_ERR_REQ_CONTENT_LENGTH_MISMATCHby retrying HTTP stream appends with fresh bodies after confirmed 429s, using the shared throttle wait policy. Retry only connection-refused, DNS, and connect-timeout failures; surface other transport errors without replay.
5.2.1
12 Oct 2026@http-samc - Compress workflow arguments on the libuv threadpool when starting a run, so large inputs no longer block the caller's event loop during zstd compression.
@http-samc - Add a
compressArgumentsoption tostart(); passfalseto store the run's arguments uncompressed when the inputs are known to be incompressible.@pranaygp - Record the queue namespace on a run's
executionContext.queueNamespaceinstart(), so restart recovery re-enqueues the run to its own namespace.
@workflow/core@5.2.1
@http-samc - Compress workflow arguments on the libuv threadpool when starting a run, so large inputs no longer block the caller's event loop during zstd compression.
@http-samc - Add a
compressArgumentsoption tostart(); passfalseto store the run's arguments uncompressed when the inputs are known to be incompressible.@pranaygp - Record the queue namespace on a run's
executionContext.queueNamespaceinstart(), so restart recovery re-enqueues the run to its own namespace.
@workflow/cli@5.0.4
@pranaygp - Improve
workflow inspectfor long runs and scoped lookups: add--allfor complete steps, events, and sleeps listings, print reusable cursor hints, and keep pagination on the read path that issued the cursor. Support event ID and short workflow-name lookups, require--runIdfor individual steps, events, and streams, fixstto mean streams, include run IDs in stream hints, and exit non-zero when a stream read fails.
@workflow/world@5.0.4
@VaguelySerious - Add
InBandSupersededErrorand optionalinBand/expectedSeqInBandevent-create params for the in-band writer fence.@workflow/world-vercelforwards them, does not retry a fenced write in-process, and records the fence on its event spans. The runtime does not use them yet.@pranaygp - Add optional
Queue.registerRoute()andQueue.registerHandler(), implemented by@workflow/world-localand@workflow/world-postgres, so a queue consumer other than the Workflow SDK receives its own prefix's messages on its own route or in process.reenqueueActiveRuns()re-enqueues a run to the queue namespace it recorded, and@workflow/world-postgreskeeps a job's queue prefix.@VaguelySerious - Implement the optional in-band writer fence and list snapshot in
@workflow/world-localand@workflow/world-postgres, declared with the newinBandFencecapability.@VaguelySerious - Report
deliveryCountandcreatedAtin queue handler meta on@workflow/world-localand@workflow/world-postgres.@pranaygp -
@workflow/world-verceldeclares theinBandFencecapability (its backend refuses a stale in-band write on every run with an event sequencer, and answers an in-band write on an older run with a 400), and passes on the in-band counts its backend reports:snapshotonevents.listandallocatedon a singleevents.create. TheinBandFencecontract lets a World list no snapshot when its refusals carry both counters, and@workflow/world-testingtakes the counters from a refusal for such a World.
@workflow/world-local@5.1.1
@pranaygp - Add optional
Queue.registerRoute()andQueue.registerHandler(), implemented by@workflow/world-localand@workflow/world-postgres, so a queue consumer other than the Workflow SDK receives its own prefix's messages on its own route or in process.reenqueueActiveRuns()re-enqueues a run to the queue namespace it recorded, and@workflow/world-postgreskeeps a job's queue prefix.@VaguelySerious - Implement the optional in-band writer fence and list snapshot in
@workflow/world-localand@workflow/world-postgres, declared with the newinBandFencecapability.@fazxes - Fix
initDataDir()crashing on Bun for a new data directory: Bun'sopendir()reports a missing directory on the first read, not when it is opened.@pranaygp - Fix in-band event count conflicts when multiple processes write events, and fix count not surviving world restarts
@pranaygp - Register a run's stream names under a lock so
streams.listno longer drops a stream when several of the run's streams first write at once. A stream written again afterclear()is listed again.@VaguelySerious - Report a message's cumulative
deliveryCountacross{ timeoutSeconds }redeliveries on@workflow/world-postgres.@VaguelySerious - Report
deliveryCountandcreatedAtin queue handler meta on@workflow/world-localand@workflow/world-postgres.
@workflow/world-postgres@5.0.4
@VaguelySerious - Fix a process crash when the database closes an idle connection
@pranaygp - Add optional
Queue.registerRoute()andQueue.registerHandler(), implemented by@workflow/world-localand@workflow/world-postgres, so a queue consumer other than the Workflow SDK receives its own prefix's messages on its own route or in process.reenqueueActiveRuns()re-enqueues a run to the queue namespace it recorded, and@workflow/world-postgreskeeps a job's queue prefix.@VaguelySerious - Implement the optional in-band writer fence and list snapshot in
@workflow/world-localand@workflow/world-postgres, declared with the newinBandFencecapability.@VaguelySerious - Report a message's cumulative
deliveryCountacross{ timeoutSeconds }redeliveries on@workflow/world-postgres.@pranaygp - Honor
pagination.sortOrderinruns.listandsteps.list, which always returned newest first.@VaguelySerious - Report
deliveryCountandcreatedAtin queue handler meta on@workflow/world-localand@workflow/world-postgres.
@workflow/world-vercel@5.2.1
@VaguelySerious - Add
InBandSupersededErrorand optionalinBand/expectedSeqInBandevent-create params for the in-band writer fence.@workflow/world-vercelforwards them, does not retry a fenced write in-process, and records the fence on its event spans. The runtime does not use them yet.@pranaygp -
@workflow/world-verceldeclares theinBandFencecapability (its backend refuses a stale in-band write on every run with an event sequencer, and answers an in-band write on an older run with a 400), and passes on the in-band counts its backend reports:snapshotonevents.listandallocatedon a singleevents.create. TheinBandFencecontract lets a World list no snapshot when its refusals carry both counters, and@workflow/world-testingtakes the counters from a refusal for such a World.
@workflow/world-testing@5.0.4
@VaguelySerious - Implement the optional in-band writer fence and list snapshot in
@workflow/world-localand@workflow/world-postgres, declared with the newinBandFencecapability.@pranaygp -
@workflow/world-verceldeclares theinBandFencecapability (its backend refuses a stale in-band write on every run with an event sequencer, and answers an in-band write on an older run with a 400), and passes on the in-band counts its backend reports:snapshotonevents.listandallocatedon a singleevents.create. TheinBandFencecontract lets a World list no snapshot when its refusals carry both counters, and@workflow/world-testingtakes the counters from a refusal for such a World. - workflow@5.2.1
@workflow/errors@5.0.4
@VaguelySerious - Add
InBandSupersededErrorand optionalinBand/expectedSeqInBandevent-create params for the in-band writer fence.@workflow/world-vercelforwards them, does not retry a fenced write in-process, and records the fence on its event spans. The runtime does not use them yet.
@workflow/utils@5.0.2
@pranaygp - Add optional
Queue.registerRoute()andQueue.registerHandler(), implemented by@workflow/world-localand@workflow/world-postgres, so a queue consumer other than the Workflow SDK receives its own prefix's messages on its own route or in process.reenqueueActiveRuns()re-enqueues a run to the queue namespace it recorded, and@workflow/world-postgreskeeps a job's queue prefix.
5.2.0
8 Oct 2026- security
@TooTallNate - Upgrade
react-routerand@react-router/*to 7.18.4 to address CVE-2026-34077 and GHSA-qwww-vcr4-c8h2 @pranaygp - Start the queued branches of a wide
Promise.allfan-out sooner. The batched fan-out now commits its writes increateBatchcalls of at most 16 events instead of 32. Each queued branch's message waits on its chunk's commit and then its chunk's batched publish, and both are faster for smaller chunks. In production sweeps, the last branch of a 64-branch fan-out started about 90 ms sooner at p50, and of a 128-branch fan-out about 200 ms sooner, with no change to the first branch at those widths.@VaguelySerious - Deliver a hook payload to the pending await when an earlier
Promise.raceover the same hook was lost
@workflow/core@5.2.0
@pranaygp - Start the queued branches of a wide
Promise.allfan-out sooner. The batched fan-out now commits its writes increateBatchcalls of at most 16 events instead of 32. Each queued branch's message waits on its chunk's commit and then its chunk's batched publish, and both are faster for smaller chunks. In production sweeps, the last branch of a 64-branch fan-out started about 90 ms sooner at p50, and of a 128-branch fan-out about 200 ms sooner, with no change to the first branch at those widths.@VaguelySerious - Deliver a hook payload to the pending await when an earlier
Promise.raceover the same hook was lost@TooTallNate - Reject lifecycle registration inside steps, preserve reporting diagnostics for unreadable errors, and document executor registration and stream-lifetime constraints.
@TooTallNate - Enable VM-memory snapshotting by default for the QuickJS engine, with a threshold of 1000 events. Set
WORKFLOW_SNAPSHOT_THRESHOLD=0to opt out. Runs without an encryption key (for example on world-local and world-postgres) are still not snapshotted unlessWORKFLOW_SNAPSHOT_ALLOW_UNENCRYPTED=1is set.@VaguelySerious - Record on the invocation trace whether out-of-band events could affect each inline step boundary
@pranaygp - Hold a turbo step's awaited
step_starteduntil the backgroundedrun_startedlands, so an explicitWORKFLOW_OPTIMISTIC_INLINE_START=0no longer gets its first step rejected for a run that has not started yet.
@workflow/cli@5.0.3
@withkarann - Ship an oclif command manifest so the CLI loads only the command being run, and skip loading the runtime on exit when no World was created.
workflow --versionstarts in about 50 ms instead of 650 ms.
@workflow/world@5.0.3
@karthikscale3 - Reduce redundant schema compilation by compiling final event schemas only and reusing compiled v4 event-response and paginated response schemas.
@workflow/world-local@5.1.0
@ruiconti - Store event and step files in one directory per run for faster reads. Local run data written by earlier releases is deleted on upgrade.
@pranaygp - Make a tagged
clear()delete only its own tag's lock files, so it no longer reopens another tag's disposed hooks mid-run.
@workflow/world-vercel@5.2.0
@alangenfeld - Stream writes now upgrade to WebSocket by default; set
WORKFLOW_STREAMS_TRANSPORT=httpto opt out.@karthikscale3 - Reduce redundant schema compilation by compiling final event schemas only and reusing compiled v4 event-response and paginated response schemas.
@workflow/web@5.0.3
- security
@TooTallNate - Upgrade
react-routerand@react-router/*to 7.18.4 to address CVE-2026-34077 and GHSA-qwww-vcr4-c8h2
@workflow/swc-plugin@5.0.1
@karthikscale3 - Stabilize nested step IDs across scopes and SWC transform modes. Self-hosted runs that already recorded one of the previously colliding IDs may report a replay divergence if they continue on upgraded code; restart those in-flight runs after upgrading.
5.1.0
6 Oct 2026@wycats - Export the existing
Serializabletype from@workflow/coreandworkflow.@TooTallNate - Remove the unused, stale
vm-serde-bundle.generated.tsleft over from the retired in-VM QuickJS serializer.@alangenfeld - Wait for run creation before writing to writable streams passed as arguments to turbo steps.
@workflow/core@5.1.0
@wycats - Export the existing
Serializabletype from@workflow/coreandworkflow.@TooTallNate - Remove the unused, stale
vm-serde-bundle.generated.tsleft over from the retired in-VM QuickJS serializer.@alangenfeld - Wait for run creation before writing to writable streams passed as arguments to turbo steps.
@alangenfeld - Mark
step_failedwrites that record a failed step body withafterStepBody, so a World can keep waiting out a throttled write instead of re-running the body.@alangenfeld - Release drained stream writer sockets without closing the shared stream, preserve handle reuse over HTTP, and dispose transports when public writable streams abort. Propagate source failures to readers of flushable stream pipes.
@TooTallNate - Serialize only the viewed bytes of a
Float16Array(no longer the whole NodeBufferpool behind it), and supportFloat16Arrayin the QuickJS engine with the same wire format as the node:vm engine.@VaguelySerious - Fix cross-deployment hook resumes and starts writing zstd payloads to runs on Node.js versions that cannot decode them. Required for upgrading to a newer Node.js version while existing runs on older Node.js versions are still receiving hooks.
@workflow/world@5.0.2
@alangenfeld - Mark
step_failedwrites that record a failed step body withafterStepBody, so a World can keep waiting out a throttled write instead of re-running the body.@alangenfeld - Release drained stream writer sockets without closing the shared stream, preserve handle reuse over HTTP, and dispose transports when public writable streams abort. Propagate source failures to readers of flushable stream pipes.
@VaguelySerious - Fix cross-deployment hook resumes and starts writing zstd payloads to runs on Node.js versions that cannot decode them. Required for upgrading to a newer Node.js version while existing runs on older Node.js versions are still receiving hooks.
@workflow/world-local@5.0.2
@alangenfeld - Prevent duplicate hook creation events when a retry publishes before the original token-claim owner.
@workflow/world-postgres@5.0.2
@VaguelySerious - Reconnect the stream and run-status
LISTENconnection after the database drops it, instead of crashing the process.
@workflow/world-vercel@5.1.0
@VaguelySerious - Default the events transport to WebSockets. Set
WORKFLOW_EVENTS_TRANSPORT=httpto opt out.@pranaygp - Upgrade
@vercel/queueto 0.6.0 so queue callbacks for messages that are already claimed or processed (409 / 410) respond 200 instead of loggingQueue callback errorand returning 500@alangenfeld - Wait out a throttled (429) write recording a step body's outcome until the invocation's deadline instead of 30 seconds, and resend a throttled event-log read from its cursor instead of restarting it.
@alangenfeld - Release drained stream writer sockets without closing the shared stream, preserve handle reuse over HTTP, and dispose transports when public writable streams abort. Propagate source failures to readers of flushable stream pipes.
@VaguelySerious - Upgrade
@vercel/queueto 0.8.0 so throttled queue sends honor the server'sRetry-Afterand queue errors carry clean messages
@workflow/web@5.0.2
@mitul-s - De-duplicate separate shadcn button implementations between
@workflow/web-sharedand@workflow/web
@workflow/web-shared@5.0.2
@mitul-s - De-duplicate separate shadcn button implementations between
@workflow/web-sharedand@workflow/web
@workflow/builders@5.0.2
@VaguelySerious - Fail the build when the workflow bundle still contains
require(). The workflow sandbox has norequire, so an import esbuild left external (most often a Node.js builtin reached through a transitive dependency or a re-export) or an unresolved dynamicrequire()used to produce a bundle that threwReferenceError: require is not definedon its first load. The build now reports the specifier, the module that imported it and the import chain back to user code. Arequire()inside atry/catchblock, or behind atypeof requirecheck, is left alone, since that is how packages probe for an optional dependency and the call either fails harmlessly or never runs. SetWORKFLOW_ALLOW_UNSAFE_FLOW_BUNDLE=1to downgrade the failure to a warning.
@workflow/next@5.0.2
@VaguelySerious - Fail the build when the workflow bundle still contains
require(). The workflow sandbox has norequire, so an import esbuild left external (most often a Node.js builtin reached through a transitive dependency or a re-export) or an unresolved dynamicrequire()used to produce a bundle that threwReferenceError: require is not definedon its first load. The build now reports the specifier, the module that imported it and the import chain back to user code. Arequire()inside atry/catchblock, or behind atypeof requirecheck, is left alone, since that is how packages probe for an optional dependency and the call either fails harmlessly or never runs. SetWORKFLOW_ALLOW_UNSAFE_FLOW_BUNDLE=1to downgrade the failure to a warning.
@workflow/utils@5.0.1
@pranaygp -
sleep(),RetryableError'sretryAfter, and a hook'sexperimental_minRetentionnow throw on an Invalid Date, or on a duration that ends past the latest time aDatecan hold, instead of sending the Invalid Date to the World.
@workflow/nest@5.1.0
@pranaygp - Harden the NestJS integration against the framework features a real application uses. Fastify applications now boot correctly, queue deliveries are no longer capped at 100,
app.enableVersioning()no longer moves the workflow routes,setGlobalPrefix(prefix, { exclude })is honoured,isWorkflowRequest(context)export added, the Vercel app function is bundled for the runtime it is deployed on,--external <pkgs>is honored, and the builder warns when a second copy of@nestjs/coreis present
Dependency tracking · free for 3 projects
Know when your own dependencies move
workflow had 1 security advisory in the last 12 months. Inlinr emails you the day one touches a project of yours, with the version that fixes it.
Advisories reach you
An email when a critical or high advisory affects a project, before the next install.
Upgrades checked first
Peer ranges, Node, ESM-only and types changes read before you bump.
Only what matters
Majors and breaking notes stay; patches and sibling bumps fold into one line.
Registry facts last checked 22 Oct 2026. Releases and advisories last read 22 Oct 2026.