Skip to content

fix(core): start forwarded writable key lookup on first write - #3955

Closed
withkarann wants to merge 1 commit into
vercel:mainfrom
withkarann:fix/forwarded-writable-key-rejection
Closed

withkarann wants to merge 1 commit into
vercel:mainfrom
withkarann:fix/forwarded-writable-key-rejection

Conversation

@withkarann

Copy link
Copy Markdown
Contributor

Description

Fixes #3935.

When a step's arguments or a run's return value contain a writable forwarded from another run, the reviver started the encryption key lookup for that run right away and stored the promise. Nothing awaited it until the first write. When the lookup failed first, for example when the fallback run metadata request timed out, the rejection had no handler and Node exited the process.

The lookup is now wrapped in a memoized thunk, so it starts on the first write and a failure errors that stream instead. EncryptionKeyParam already accepts a thunk, and the readable side already defers its key lookup the same way. Both reviver sites use the helper.

One trade-off: forwarded writables without a public key (descriptors from older SDKs) now make the lookup requests on the first write instead of overlapping them with execution, and writables that are never written to make no requests at all. If keeping the prefetch matters more, the smaller alternative is to keep the eager call and mark the stored promise as handled. Happy to switch.

How did you test your changes?

New test next to the existing forwarded writable tests in serialization.test.ts. It hydrates a forwarded writable with no deployment id and no public key, mocks runs.get to reject with a WorkflowWorldError (code: 'TIMEOUT'), and checks that no unhandledRejection fires and no request is made before the first write, then that the writer's closed promise rejects with the timeout as its cause. On main the test fails because the request is made during hydration.

cd packages/core && pnpm vitest run src/serialization.test.ts

PR Checklist - Required to merge

  • 📦 pnpm changeset was run to create a changelog for this PR
  • 🔒 DCO sign-off passes (run git commit --signoff on your commits)
  • 📝 Ping @vercel/workflow in a comment once the PR is ready, and the above checklist is complete

Hydrating a forwarded writable started the encryption key lookup for the
target run right away and stored the promise. Nothing awaited it until
the first chunk was written, so when the lookup failed first, for
example a run metadata request that timed out, the rejection was
unhandled and took the process down.

Wrap the lookup in a memoized thunk so it runs on the first write and
its failure errors that stream instead. This matches how the readable
side already defers its key lookup.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: withkarann <31102185+withkarann@users.noreply.github.com>
@withkarann
withkarann requested a review from a team as a code owner September 3, 2026 09:22
@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8863c2d

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

This PR includes changesets to release 16 packages
Name Type
@workflow/core Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/vitest Patch
@workflow/web-shared Patch
@workflow/web Patch
workflow Patch
@workflow/world-testing 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 Sep 3, 2026

Copy link
Copy Markdown
Contributor

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

A member of the Team first needs to authorize it.

@withkarann

Copy link
Copy Markdown
Contributor Author

Closing in favor of #4175, which carried this fix onto current main with the extra tests and the stable analysis. Thanks for the credit and for landing it.

@withkarann withkarann closed this Sep 21, 2026
@withkarann
withkarann deleted the fix/forwarded-writable-key-rejection branch September 30, 2026 21:09
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.

A WorkflowWorldError timeout is an unhandled rejection and kills the process (exit 128)

1 participant