Skip to content

fix(core): fail runs delivered to the wrong deployment#2960

Draft
alangenfeld wants to merge 1 commit into
mainfrom
alangenfeld/fail-cross-deployment-runs
Draft

fix(core): fail runs delivered to the wrong deployment#2960
alangenfeld wants to merge 1 commit into
mainfrom
alangenfeld/fail-cross-deployment-runs

Conversation

@alangenfeld

@alangenfeld alangenfeld commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

A run created on one deployment whose queue callbacks route to another (common on preview branches, where a superseded deployment is deactivated) fails cryptically: the step handler resolves the per-run encryption key from the bare runId, derives it from the wrong deployment's master key, and throws a RuntimeDecryptionError before user code runs. The queue retry callback swallows it, so the run dies as a blank "exceeded max retries."

A run may only execute on the deployment that created it (continuing elsewhere risks code skew). This detects delivery to the wrong deployment and fails the run with the new DEPLOYMENT_MISMATCH error code.

  • Guards every entrypoint that executes a run — main workflow replay, background step, and the queue step handler — so the run is stopped before any workflow code, inline step, or queue step runs.
  • Records the failure without the origin deployment's key. That key is fetched from the origin's API, which is often gone once a run outlives its deployment — depending on it would throw and drop us back into silent retry-exhaustion. The error is written unencrypted (deployment ids only) and the plaintext errorCode is what observability and the UI key off (describeRunError maps it to an actionable hint).
  • Adds RUN_ERROR_CODES.DEPLOYMENT_MISMATCH; WorkflowDeploymentMismatchError classifies to it.
  • Documents the failure under Errors for both docs versions.

Closes #2816. The issue's second half — the queue retry callback swallowing errors — was fixed separately.

Docs Preview

Page v4 v5
errors/deployment-mismatch /docs/errors/deployment-mismatch /v5/docs/errors/deployment-mismatch

Follow-up (separate repo)

  • Dashboard: link the DEPLOYMENT_MISMATCH code to the new docs page.

Testing

  • pnpm --filter @workflow/core... build
  • pnpm --filter @workflow/core exec vitest run src --exclude src/vm/uint8array-base64.test.ts (1,430 tests)
  • pnpm --filter @workflow/errors test (38 tests)
  • core and errors typechecks

The excluded VM test has existing cross-realm assertion failures on local Node 26; the repository supports through Node 24.

@changeset-bot

changeset-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a359b5e

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/errors 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/world-local Patch
@workflow/world-postgres Patch
@workflow/world-vercel Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/nuxt Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite 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 Jul 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview, Comment Jul 16, 2026 10:03pm
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jul 16, 2026 10:03pm
example-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-astro-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-express-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-fastify-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-hono-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-nitro-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-nuxt-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-sveltekit-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-tanstack-start-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workbench-vite-workflow Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workflow-docs Ready Ready Preview, Comment, Open in v0 Jul 16, 2026 10:03pm
workflow-swc-playground Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workflow-tarballs Ready Ready Preview, Comment Jul 16, 2026 10:03pm
workflow-web Ready Ready Preview, Comment Jul 16, 2026 10:03pm

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

All tests passed

Summary

Passed Failed Skipped Total
✅ 💻 Local Development 1617 0 219 1836
✅ 📦 Local Production 1617 0 219 1836
✅ 🐘 Local Postgres 1617 0 219 1836
✅ 🪟 Windows 153 0 0 153
✅ 📋 Other 768 0 150 918
Total 5772 0 807 6579

Details by Category

✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-canary 134 0 19
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-canary 134 0 19
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 128 0 25
✅ express-stable 128 0 25
✅ fastify-stable 128 0 25
✅ hono-stable 128 0 25
✅ nextjs-turbopack-canary 134 0 19
✅ nextjs-turbopack-stable 153 0 0
✅ nextjs-webpack-canary 134 0 19
✅ nextjs-webpack-stable 153 0 0
✅ nitro-stable 128 0 25
✅ nuxt-stable 128 0 25
✅ sveltekit-stable 147 0 6
✅ vite-stable 128 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 153 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 128 0 25
✅ e2e-local-dev-tanstack-start- 128 0 25
✅ e2e-local-postgres-nest-stable 128 0 25
✅ e2e-local-postgres-tanstack-start- 128 0 25
✅ e2e-local-prod-nest-stable 128 0 25
✅ e2e-local-prod-tanstack-start- 128 0 25

📋 View full workflow run


Some E2E test jobs failed:

  • Vercel Prod: failure
  • Local Dev: success
  • Local Prod: success
  • Local Postgres: success
  • Windows: success

Check the workflow run for details.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

📊 Workflow Benchmarks

commit 589da5d · Thu, 16 Jul 2026 22:19:45 GMT · run logs

Backend: vercel · app: nextjs-turbopack

Metric Scenario Avg (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS stream 1250 (+15%) 1621 🔴 1689 🔴 1734 🔴 30
TTFS hook + stream 1542 (+7.9%) 1961 🔴 1981 🔴 2365 🔴 30
STSO 1020 steps (1-20) 266 (-12%) 312 🔴 351 🔴 381 🔴 19
STSO 1020 steps (101-120) 390 (-10.0%) 424 🔴 484 🔴 705 🔴 19
STSO 1020 steps (1001-1020) 862 (+0.7%) 897 🔴 1006 🔴 1356 🔴 19
WO stream 1250 (+15%) 1621 1689 1734 30
WO hook + stream 1542 (+7.9%) 1961 1981 2365 30
SL stream 4536 (-3.1%) 5399 🔴 5586 🔴 5727 🔴 30
SL hook + stream 4873 (±0%) 5431 🔴 5587 🔴 6557 🔴 30
📜 Previous results (2)

3ef6bcc

Thu, 16 Jul 2026 18:47:46 GMT · run logs

vercel / nextjs-turbopack

Metric Scenario Avg (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS stream 1353 (+9.8%) 1808 🔴 1920 🔴 2338 🔴 30
TTFS hook + stream 1586 (+10%) 1986 🔴 2091 🔴 2330 🔴 30
STSO 1020 steps (1-20) 317 (+19%) 349 🔴 511 🔴 641 🔴 19
STSO 1020 steps (101-120) 475 (+6.2%) 570 🔴 622 🔴 628 🔴 19
STSO 1020 steps (1001-1020) 889 (+4.4%) 943 🔴 990 🔴 1029 🔴 19
WO stream 1353 (+9.8%) 1808 1920 2338 30
WO hook + stream 1586 (+10%) 1986 2091 2330 30
SL stream 4294 (-1.7%) 5084 🔴 5967 🔴 6236 🔴 30
SL hook + stream 5083 (-2.0%) 5656 🔴 5815 🔴 5985 🔴 30

1da67fa

Thu, 16 Jul 2026 18:23:02 GMT · run logs

vercel / nextjs-turbopack

Metric Scenario Avg (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS stream 1145 (-7.1%) 1681 🔴 1712 🔴 1885 🔴 30
TTFS hook + stream 1671 (+16%) 1990 🔴 2022 🔴 2331 🔴 30
STSO 1020 steps (1-20) 302 (+14%) 351 🔴 448 🔴 509 🔴 19
STSO 1020 steps (101-120) 430 (-3.8%) 465 🔴 540 🔴 558 🔴 19
STSO 1020 steps (1001-1020) 902 (+6.0%) 933 🔴 1064 🔴 1205 🔴 19
WO stream 1145 (-7.1%) 1681 1712 1885 30
WO hook + stream 1671 (+16%) 1990 2022 2331 30
SL stream 4373 (±0%) 5802 🔴 5920 🔴 6054 🔴 30
SL hook + stream 4682 (-9.7%) 5052 🔴 5708 🔴 5863 🔴 30

Avg deltas compare against the most recent benchmark run on main at the time of this run.

Metrics — TTFS: time to first step body execution · STSO: step-to-step overhead (gap between consecutive step bodies) · WO: workflow overhead (time outside step bodies, client start → last step body exit) · SL: stream latency (first chunk write → visible to the reader)

Scenarios — stream: one step that streams chunks back to the client; no hooks, so the run stays in turbo mode · hook + stream: registers a hook before the same streaming step, which exits turbo mode · 1020 steps: 1020 trivial sequential steps; STSO is measured between consecutive steps in the given step ranges

🟢/🔴 mark percentiles within/above target. Targets (p75/p90/p99, ms) — TTFS 200/300/600 · SL 50/60/125 · STSO (1-20) 20/30/60 · STSO (101-120) 30/45/90 · STSO (1001-1020) 40/60/120

TTFS/WO compare client vs deployment clocks and SL compares the step runner’s clock vs the client’s (NTP-synced in CI). WO ends at the last step body exit, the closest observable proxy for the final step-completion request.

@alangenfeld
alangenfeld force-pushed the alangenfeld/fail-cross-deployment-runs branch from 1da67fa to 3ef6bcc Compare July 16, 2026 18:25
@alangenfeld
alangenfeld force-pushed the alangenfeld/fail-cross-deployment-runs branch from 3ef6bcc to 589da5d Compare July 16, 2026 21:58
Signed-off-by: Alex Langenfeld <alex.langenfeld@vercel.com>
@alangenfeld
alangenfeld force-pushed the alangenfeld/fail-cross-deployment-runs branch from 589da5d to a359b5e Compare July 16, 2026 22:33
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Deployment failed with the following error:

Creating the Deployment Timed Out.

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

Labels

None yet

Projects

None yet

1 participant