Skip to content

fix(core): preserve durable cancellation recovery - #3578

Draft
LunarianDev wants to merge 23 commits into
vercel:mainfrom
LunarianDev:codex/task7-active-step-cancel
Draft

fix(core): preserve durable cancellation recovery#3578
LunarianDev wants to merge 23 commits into
vercel:mainfrom
LunarianDev:codex/task7-active-step-cancel

Conversation

@LunarianDev

Copy link
Copy Markdown

Summary

  • add durable active-step cancellation receipts and replay-safe abort delivery
  • add local World capabilities for idempotent run start, hook resume, and keyed stream append
  • make local stream/run projection, dispatch ownership, recovery, and step identity stable across process loss
  • keep Postgres and Vercel exact capabilities fail-closed

Verification

  • focused Core and world-local suites, including real child-process/HTTP recovery and deterministic cross-process race matrices
  • Core/world/world-local TypeScript checks
  • final reviewer-escalated audit converged with no findings

Release boundary

This is a draft upstream repair. No package publication or downstream adoption is included.

@changeset-bot

changeset-bot Bot commented Aug 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 20790bb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
@workflow/core Patch
workflow Patch
@workflow/world Patch
@workflow/world-local Patch
@workflow/world-postgres Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web-shared Patch
@workflow/web Patch
@workflow/world-testing Patch
@workflow/world-vercel Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

@LunarianDev is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Comment on lines +879 to +881
await waitForAbortReaderCleanup(
cancelAbortReaders(...args, thisVal, hydratedInput.closureVars)
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await waitForAbortReaderCleanup(
cancelAbortReaders(...args, thisVal, hydratedInput.closureVars)
);
//
// The wait is best-effort: `waitForAbortReaderCleanup` rejects on its
// 250ms bound (a service-backed World's remote stream-cancel can exceed
// this — the cancel may hit the network) or if `reader.cancel()` throws.
// Neither outcome must fail the step: propagating it would (1) spuriously
// fail/retry an otherwise-successful signal-bearing step, re-running user
// code with duplicate side effects, and (2) mask a genuine user-code
// error by skipping the `throw userCodeError` re-raise below, corrupting
// retry classification (e.g. a FatalError becoming a generic cleanup
// error). Swallow and log instead, matching the reader teardown's prior
// fire-and-forget contract. The teardown is also tracked in `ops`, so a
// slow-but-eventual cancel still gets a chance to settle in the flush
// window below.
try {
await waitForAbortReaderCleanup(
cancelAbortReaders(...args, thisVal, hydratedInput.closureVars)
);
} catch (cleanupErr) {
runtimeLogger.warn('Abort stream reader cleanup did not settle', {
workflowRunId,
stepId,
error:
cleanupErr instanceof Error
? cleanupErr.message
: String(cleanupErr),
});
}

Abort-reader cleanup rejection (250ms timeout or reader.cancel() throw) is caught by the step's outer catch, spuriously failing/retrying a successful signal-bearing step and masking genuine user-code errors.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant