Skip to content

fix(core): make deploymentId 'latest' a no-op in non-Vercel worlds#2397

Open
pranaygp wants to merge 2 commits into
mainfrom
pgp/deployment-id-latest
Open

fix(core): make deploymentId 'latest' a no-op in non-Vercel worlds#2397
pranaygp wants to merge 2 commits into
mainfrom
pgp/deployment-id-latest

Conversation

@pranaygp

@pranaygp pranaygp commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

start({ deploymentId: 'latest' }) previously threw a WorkflowRuntimeError in any World that doesn't implement resolveLatestDeploymentId() — i.e. local dev and Postgres. That meant a workflow which opts into 'latest' to target the newest deployment on Vercel would fail outright in local development, even though there's nothing for it to do there.

Resolving 'latest' only means something in worlds with atomic, immutable deployments (currently Vercel). Other worlds have no notion of multiple deployments to resolve between. So instead of throwing, the SDK now logs a warning (once per process) and falls back to the current deployment, making 'latest' an effective no-op outside Vercel.

[workflow-sdk] deploymentId: 'latest' has no effect in this world and was ignored.
It is only supported by worlds with atomic deployments, such as Vercel.
The run will target the current deployment.

Changes

  • packages/core/src/runtime/start.ts — when deploymentId === 'latest' and the World has no resolveLatestDeploymentId(), warn via runtimeLogger.warn and fall back to currentDeploymentId instead of throwing. The warning is gated behind a once-per-process guard (hasWarnedLatestNoOp, mirroring the warnOnce pattern in constants.ts) so tight local/Postgres dev loops aren't flooded. Updated the StartOptionsWithDeploymentId JSDoc.
  • packages/core/src/runtime/start.test.ts — replaced the "should throw" unit test with one asserting the warning is logged and the run falls back to the current deployment ID (in both the run_created event and the queue dispatch); added a test asserting the warning fires exactly once across repeated 'latest' starts. Spies are now restored in afterEach via vi.restoreAllMocks() so a throwing assertion can't leak the runtimeLogger.warn spy into later tests.
  • packages/core/e2e/e2e.test.ts — new test gated to non-Vercel worlds (skipIf(WORKFLOW_VERCEL_ENV)) that starts a workflow with deploymentId: 'latest' and asserts it completes — directly exercising the no-op against the real local/Postgres worlds. (This is the e2e coverage that was previously missing for this option.)
  • docs — added a note to the deploymentId: "latest" section of both v4 and v5 start.mdx describing the no-op-with-warning behavior in non-Vercel worlds.

Implementation note

The fallback assigns deploymentId = currentDeploymentId (rather than leaving the 'latest' sentinel in place). This is deliberate: the downstream if (deploymentId === currentDeploymentId) gate then takes the same-deployment fast path — byte-stream framing + compression enabled, no cross-deployment health-probe round-trip — which is exactly right for local/Postgres, where 'latest' semantically means "right here." (h/t @TooTallNate for calling this out.)

Behavior matrix

World Before After
Vercel resolves via API resolves via API (unchanged)
local ❌ throws ⚠️ warns once, targets current deployment
Postgres ❌ throws ⚠️ warns once, targets current deployment

Testing

  • pnpm vitest run src/runtime/start.test.ts → 28/28 pass (incl. warn+fallback and warn-once tests)
  • pnpm --filter @workflow/core typecheck → clean
  • New e2e test runs on non-Vercel matrix entries in CI.

Docs Preview

Page v4 v5
start — Using deploymentId: "latest" /docs/…/start#using-deploymentid-latest /v5/docs/…/start#using-deploymentid-latest

(Behind deployment protection — requires Vercel team access.)

🤖 Generated with Claude Code

Previously, start({ deploymentId: 'latest' }) threw a WorkflowRuntimeError
in any World that doesn't implement resolveLatestDeploymentId() (local dev,
Postgres). That meant a workflow which opts into 'latest' on Vercel would
fail outright in local development.

Resolving 'latest' only means something in worlds with atomic, immutable
deployments. In other worlds there is nothing to resolve between, so instead
of throwing we now log a warning and fall back to the current deployment,
making 'latest' an effective no-op there.

- start.ts: warn + fall back to currentDeploymentId instead of throwing
- start.test.ts: replace the "should throw" test with a warn + fallback test
- e2e.test.ts: assert 'latest' completes (no-op) on non-Vercel worlds
- docs: note the no-op behavior in v4 + v5 start.mdx

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp pranaygp requested a review from a team as a code owner June 13, 2026 06:27
Copilot AI review requested due to automatic review settings June 13, 2026 06:27
@changeset-bot

changeset-bot Bot commented Jun 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 17604c2

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 Jun 13, 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 Jun 14, 2026 8:14am
example-nextjs-workflow-webpack Ready Ready Preview, Comment Jun 14, 2026 8:14am
example-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-astro-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-express-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-fastify-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-hono-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-nitro-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-nuxt-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-sveltekit-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-tanstack-start-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workbench-vite-workflow Ready Ready Preview, Comment Jun 14, 2026 8:14am
workflow-docs Ready Ready Preview, Comment, Open in v0 Jun 14, 2026 8:14am
workflow-swc-playground Ready Ready Preview, Comment Jun 14, 2026 8:14am
workflow-tarballs Ready Ready Preview, Comment Jun 14, 2026 8:14am
workflow-web Ready Ready Preview, Comment Jun 14, 2026 8:14am

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

📊 Benchmark Results

⚠️ Results below are stale and not from the latest commit. This comment will be updated when CI completes on the latest run.

Benchmarks are running...


_Started at: _


📊 Benchmark Results

📈 Comparing against baseline from main branch. Green 🟢 = faster, Red 🔺 = slower.

workflow with no steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 0.040s (-10.3% 🟢) 1.006s (~) 0.966s 10 1.00x
💻 Local Express 0.043s (-2.5%) 1.006s (~) 0.962s 10 1.08x
🐘 Postgres Nitro 0.058s (-12.5% 🟢) 1.011s (~) 0.953s 10 1.45x
🐘 Postgres Next.js (Turbopack) 0.061s (-9.6% 🟢) 1.015s (~) 0.954s 10 1.51x
💻 Local Next.js (Turbopack) 0.061s (-1.9%) 1.006s (~) 0.945s 10 1.53x
🐘 Postgres Express 0.066s (+5.1% 🔺) 1.011s (~) 0.945s 10 1.65x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.253s (-58.5% 🟢) 2.244s (-9.1% 🟢) 1.991s 10 1.00x
▲ Vercel Nitro 0.289s (-19.1% 🟢) 2.151s (-17.0% 🟢) 1.862s 10 1.14x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.093s (~) 2.006s (~) 0.914s 10 1.00x
💻 Local Express 1.098s (-0.7%) 2.007s (~) 0.909s 10 1.00x
🐘 Postgres Nitro 1.108s (~) 2.010s (~) 0.902s 10 1.01x
🐘 Postgres Express 1.109s (~) 2.010s (~) 0.901s 10 1.01x
🐘 Postgres Next.js (Turbopack) 1.125s (-1.4%) 2.007s (~) 0.882s 10 1.03x
💻 Local Next.js (Turbopack) 1.143s (~) 2.006s (~) 0.864s 10 1.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 1.599s (-9.3% 🟢) 3.669s (-4.9%) 2.070s 10 1.00x
▲ Vercel Next.js (Turbopack) 1.712s (-20.4% 🟢) 3.869s (-3.6%) 2.156s 10 1.07x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 10.518s (~) 11.023s (~) 0.505s 3 1.00x
💻 Local Express 10.545s (~) 11.023s (~) 0.478s 3 1.00x
🐘 Postgres Nitro 10.600s (~) 11.020s (~) 0.420s 3 1.01x
🐘 Postgres Express 10.669s (+1.2%) 11.018s (~) 0.349s 3 1.01x
💻 Local Next.js (Turbopack) 10.781s (~) 11.023s (~) 0.242s 3 1.03x
🐘 Postgres Next.js (Turbopack) 10.782s (-1.0%) 11.015s (~) 0.233s 3 1.03x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 13.698s (-2.0%) 16.075s (+2.1%) 2.376s 2 1.00x
▲ Vercel Next.js (Turbopack) 14.191s (-2.0%) 16.144s (-0.5%) 1.953s 2 1.04x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 13.704s (~) 14.026s (~) 0.323s 5 1.00x
💻 Local Express 13.800s (~) 14.028s (~) 0.227s 5 1.01x
🐘 Postgres Nitro 13.804s (-1.0%) 14.018s (~) 0.214s 5 1.01x
🐘 Postgres Express 14.024s (+1.5%) 14.420s (+2.9%) 0.396s 5 1.02x
🐘 Postgres Next.js (Turbopack) 14.329s (-0.6%) 15.017s (~) 0.688s 4 1.05x
💻 Local Next.js (Turbopack) 14.419s (~) 15.030s (~) 0.610s 4 1.05x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 23.110s (-5.2% 🟢) 24.726s (-5.7% 🟢) 1.616s 3 1.00x
▲ Vercel Next.js (Turbopack) 23.269s (+6.8% 🔺) 25.245s (+3.8%) 1.975s 3 1.01x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 12.350s (~) 13.025s (~) 0.675s 7 1.00x
💻 Local Express 12.533s (~) 13.026s (~) 0.492s 7 1.01x
🐘 Postgres Express 12.585s (~) 13.022s (~) 0.438s 7 1.02x
🐘 Postgres Nitro 12.685s (+0.5%) 13.021s (~) 0.335s 7 1.03x
💻 Local Next.js (Turbopack) 13.757s (~) 14.027s (-1.0%) 0.270s 7 1.11x
🐘 Postgres Next.js (Turbopack) 14.266s (+1.4%) 14.754s (+1.1%) 0.489s 7 1.16x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 32.150s (~) 33.718s (+1.5%) 1.568s 3 1.00x
▲ Vercel Nitro 32.496s (+10.1% 🔺) 34.535s (+6.8% 🔺) 2.040s 3 1.01x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.203s (-1.6%) 2.008s (~) 0.805s 15 1.00x
💻 Local Express 1.207s (-5.4% 🟢) 2.007s (~) 0.799s 15 1.00x
🐘 Postgres Express 1.214s (~) 2.008s (~) 0.795s 15 1.01x
💻 Local Nitro 1.215s (+2.6%) 2.006s (~) 0.791s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.244s (-4.8%) 2.008s (~) 0.764s 15 1.03x
💻 Local Next.js (Turbopack) 1.311s (-3.9%) 2.006s (~) 0.695s 15 1.09x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.367s (-16.6% 🟢) 4.305s (~) 1.938s 7 1.00x
▲ Vercel Nitro 2.779s (-33.4% 🟢) 4.272s (-23.9% 🟢) 1.493s 8 1.17x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.393s (-2.1%) 2.508s (+16.6% 🔺) 1.116s 12 1.00x
🐘 Postgres Nitro 1.407s (~) 2.470s (+3.2%) 1.063s 13 1.01x
🐘 Postgres Next.js (Turbopack) 1.570s (-0.7%) 2.151s (-7.2% 🟢) 0.581s 14 1.13x
💻 Local Nitro 1.726s (-2.2%) 2.006s (-3.2%) 0.280s 15 1.24x
💻 Local Express 1.869s (-9.3% 🟢) 2.150s (-14.3% 🟢) 0.281s 14 1.34x
💻 Local Next.js (Turbopack) 1.898s (+7.8% 🔺) 2.150s (~) 0.252s 14 1.36x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 3.345s (+6.4% 🔺) 5.462s (+19.4% 🔺) 2.117s 6 1.00x
▲ Vercel Nitro 3.607s (+29.1% 🔺) 5.123s (+18.3% 🔺) 1.516s 7 1.08x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.655s (+1.9%) 4.298s (+3.9%) 2.643s 7 1.00x
🐘 Postgres Express 1.675s (+2.7%) 4.011s (~) 2.337s 8 1.01x
🐘 Postgres Next.js (Turbopack) 2.977s (-7.5% 🟢) 3.886s (-3.2%) 0.909s 8 1.80x
💻 Local Nitro 4.851s (+7.7% 🔺) 5.513s (+6.4% 🔺) 0.663s 6 2.93x
💻 Local Next.js (Turbopack) 5.674s (+22.6% 🔺) 6.215s (+24.0% 🔺) 0.541s 5 3.43x
💻 Local Express 5.717s (+1.2%) 6.214s (+3.3%) 0.497s 5 3.45x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.476s (-12.8% 🟢) 5.557s (-6.4% 🟢) 2.081s 6 1.00x
▲ Vercel Next.js (Turbopack) 5.274s (-11.2% 🟢) 7.695s (+4.2%) 2.421s 4 1.52x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.201s (-1.4%) 2.007s (~) 0.807s 15 1.00x
🐘 Postgres Express 1.215s (-0.8%) 2.007s (~) 0.792s 15 1.01x
🐘 Postgres Next.js (Turbopack) 1.277s (-1.1%) 2.009s (~) 0.732s 15 1.06x
💻 Local Next.js (Turbopack) 1.409s (+3.6%) 2.007s (~) 0.598s 15 1.17x
💻 Local Nitro 1.565s (+2.0%) 2.006s (~) 0.441s 15 1.30x
💻 Local Express 1.566s (+1.2%) 2.006s (~) 0.440s 15 1.30x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.578s (-21.4% 🟢) 4.169s (-16.8% 🟢) 1.590s 8 1.00x
▲ Vercel Next.js (Turbopack) 2.867s (-26.1% 🟢) 4.745s (-8.2% 🟢) 1.878s 7 1.11x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.358s (-4.9%) 2.315s (+4.1%) 0.957s 13 1.00x
🐘 Postgres Express 1.408s (+4.5%) 2.392s (+11.2% 🔺) 0.984s 13 1.04x
🐘 Postgres Next.js (Turbopack) 1.495s (-2.6%) 2.156s (+0.7%) 0.661s 14 1.10x
💻 Local Next.js (Turbopack) 2.049s (~) 2.674s (-5.4% 🟢) 0.626s 12 1.51x
💻 Local Nitro 2.139s (+18.0% 🔺) 2.547s (+14.5% 🔺) 0.408s 13 1.58x
💻 Local Express 2.303s (+6.9% 🔺) 2.918s (+12.5% 🔺) 0.615s 11 1.70x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.707s (-54.9% 🟢) 4.421s (-41.4% 🟢) 1.714s 7 1.00x
▲ Vercel Nitro 3.468s (-12.4% 🟢) 5.329s (-5.0%) 1.861s 6 1.28x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.565s (-6.3% 🟢) 4.011s (-6.8% 🟢) 2.446s 8 1.00x
🐘 Postgres Express 1.629s (-20.9% 🟢) 3.887s (-6.2% 🟢) 2.258s 8 1.04x
🐘 Postgres Next.js (Turbopack) 3.084s (-6.5% 🟢) 3.769s (-6.1% 🟢) 0.685s 8 1.97x
💻 Local Nitro 5.301s (-2.4%) 5.847s (~) 0.546s 6 3.39x
💻 Local Next.js (Turbopack) 6.148s (+22.1% 🔺) 6.616s (+20.0% 🔺) 0.467s 5 3.93x
💻 Local Express 6.485s (+6.4% 🔺) 6.816s (+3.0%) 0.331s 5 4.14x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 4.330s (-58.0% 🟢) 6.115s (-48.4% 🟢) 1.784s 5 1.00x
▲ Vercel Next.js (Turbopack) 4.935s (+51.1% 🔺) 6.900s (+42.3% 🔺) 1.965s 5 1.14x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.576s (+1.7%) 1.006s (~) 0.430s 60 1.00x
🐘 Postgres Nitro 0.586s (+1.3%) 1.023s (+1.7%) 0.437s 59 1.02x
💻 Local Nitro 0.591s (+0.6%) 1.005s (~) 0.413s 60 1.03x
💻 Local Express 0.617s (+1.1%) 1.005s (~) 0.388s 60 1.07x
🐘 Postgres Next.js (Turbopack) 0.813s (+0.9%) 1.088s (+8.2% 🔺) 0.276s 56 1.41x
💻 Local Next.js (Turbopack) 0.916s (+5.0%) 1.039s (~) 0.123s 58 1.59x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 7.038s (+38.3% 🔺) 8.992s (+31.3% 🔺) 1.954s 7 1.00x
▲ Vercel Nitro 8.937s (+74.1% 🔺) 10.411s (+49.2% 🔺) 1.474s 6 1.27x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.402s (~) 2.030s (+1.1%) 0.627s 45 1.00x
🐘 Postgres Express 1.413s (-2.5%) 2.030s (-1.1%) 0.617s 45 1.01x
💻 Local Nitro 1.506s (~) 2.006s (~) 0.500s 45 1.07x
💻 Local Express 1.553s (+2.0%) 2.029s (+1.1%) 0.475s 45 1.11x
🐘 Postgres Next.js (Turbopack) 1.895s (-0.8%) 2.259s (+8.9% 🔺) 0.364s 41 1.35x
💻 Local Next.js (Turbopack) 2.144s (+0.7%) 3.008s (~) 0.864s 30 1.53x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 16.661s (+18.8% 🔺) 18.628s (+14.2% 🔺) 1.967s 5 1.00x
▲ Vercel Next.js (Turbopack) 18.104s (+10.6% 🔺) 20.462s (+12.8% 🔺) 2.358s 5 1.09x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 2.733s (-1.0%) 3.058s (-2.5%) 0.325s 40 1.00x
🐘 Postgres Nitro 2.795s (+2.2%) 3.136s (+3.4%) 0.341s 39 1.02x
💻 Local Nitro 3.220s (~) 4.009s (~) 0.790s 30 1.18x
💻 Local Express 3.289s (-0.9%) 4.010s (~) 0.721s 30 1.20x
🐘 Postgres Next.js (Turbopack) 3.561s (-8.3% 🟢) 4.150s (-0.8%) 0.589s 29 1.30x
💻 Local Next.js (Turbopack) 4.419s (+1.7%) 5.010s (~) 0.591s 24 1.62x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 35.480s (+15.0% 🔺) 37.049s (+12.6% 🔺) 1.569s 4 1.00x
▲ Vercel Next.js (Turbopack) 35.943s (+20.3% 🔺) 38.258s (+20.2% 🔺) 2.315s 4 1.01x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.243s (-3.3%) 1.006s (~) 0.763s 60 1.00x
🐘 Postgres Express 0.256s (+2.4%) 1.007s (~) 0.750s 60 1.06x
🐘 Postgres Next.js (Turbopack) 0.292s (-5.0%) 1.010s (-1.3%) 0.718s 60 1.20x
💻 Local Nitro 0.438s (+9.9% 🔺) 1.005s (~) 0.567s 60 1.80x
💻 Local Express 0.450s (+14.7% 🔺) 1.004s (~) 0.555s 60 1.85x
💻 Local Next.js (Turbopack) 0.543s (-6.0% 🟢) 1.005s (~) 0.462s 60 2.24x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 2.015s (+6.9% 🔺) 3.635s (-12.0% 🟢) 1.619s 17 1.00x
▲ Vercel Next.js (Turbopack) 2.548s (+3.1%) 4.440s (+9.1% 🔺) 1.892s 14 1.26x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.388s (-7.9% 🟢) 1.078s (+1.2%) 0.689s 84 1.00x
🐘 Postgres Express 0.420s (+0.6%) 1.041s (~) 0.621s 87 1.08x
🐘 Postgres Next.js (Turbopack) 0.671s (+21.5% 🔺) 1.365s (+29.6% 🔺) 0.693s 66 1.73x
💻 Local Express 2.146s (-0.8%) 2.768s (+1.9%) 0.621s 33 5.53x
💻 Local Nitro 2.183s (+3.0%) 2.797s (+5.3% 🔺) 0.615s 33 5.62x
💻 Local Next.js (Turbopack) 2.502s (+2.5%) 3.225s (+1.3%) 0.722s 28 6.44x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 3.116s (+15.0% 🔺) 4.762s (+7.2% 🔺) 1.645s 19 1.00x
▲ Vercel Next.js (Turbopack) 3.189s (+10.6% 🔺) 5.074s (+14.7% 🔺) 1.885s 18 1.02x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

workflow with 50 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.779s (-7.2% 🟢) 1.489s (-2.0%) 0.710s 81 1.00x
🐘 Postgres Express 0.827s (+1.9%) 1.371s (-13.6% 🟢) 0.544s 88 1.06x
🐘 Postgres Next.js (Turbopack) 2.170s (-16.4% 🟢) 2.968s (-13.8% 🟢) 0.798s 41 2.79x
💻 Local Nitro 9.523s (+1.9%) 10.032s (+0.8%) 0.509s 12 12.23x
💻 Local Express 10.009s (+2.1%) 10.446s (+0.8%) 0.437s 12 12.85x
💻 Local Next.js (Turbopack) 10.953s (+7.9% 🔺) 11.758s (+6.6% 🔺) 0.805s 11 14.07x

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 6.073s (-4.7%) 7.753s (-7.5% 🟢) 1.680s 16 1.00x
▲ Vercel Next.js (Turbopack) 6.877s (-10.7% 🟢) 8.745s (-6.2% 🟢) 1.868s 14 1.13x
▲ Vercel Express ⚠️ missing - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Stream Benchmarks (includes TTFB metrics)
workflow with stream

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.159s (~) 2.005s (~) 0.010s (+1.0%) 2.017s (~) 0.858s 10 1.00x
🐘 Postgres Nitro 1.161s (-0.7%) 2.001s (~) 0.001s (-15.4% 🟢) 2.009s (~) 0.848s 10 1.00x
💻 Local Express 1.165s (~) 2.005s (~) 0.012s (-2.4%) 2.019s (~) 0.854s 10 1.01x
🐘 Postgres Express 1.179s (+1.0%) 1.997s (~) 0.001s (-20.0% 🟢) 2.011s (~) 0.832s 10 1.02x
🐘 Postgres Next.js (Turbopack) 1.209s (-5.2% 🟢) 2.002s (~) 0.001s (-20.0% 🟢) 2.012s (~) 0.803s 10 1.04x
💻 Local Next.js (Turbopack) 1.221s (+1.0%) 2.004s (~) 0.012s (+17.1% 🔺) 2.020s (~) 0.799s 10 1.05x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.412s (+15.3% 🔺) 3.759s (+25.5% 🔺) 0.486s (-58.0% 🟢) 4.765s (+4.7%) 2.353s 10 1.00x
▲ Vercel Nitro 2.761s (-15.6% 🟢) 3.763s (-18.5% 🟢) 0.773s (+14.0% 🔺) 4.947s (-14.8% 🟢) 2.186s 10 1.14x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Nitro 1.573s (~) 2.010s (~) 0.013s (-8.4% 🟢) 2.025s (~) 0.452s 30 1.00x
💻 Local Express 1.598s (~) 2.011s (~) 0.012s (+2.5%) 2.025s (~) 0.427s 30 1.02x
🐘 Postgres Nitro 1.602s (~) 2.007s (~) 0.005s (-10.9% 🟢) 2.025s (~) 0.423s 30 1.02x
🐘 Postgres Express 1.622s (+1.9%) 2.005s (~) 0.005s (~) 2.028s (~) 0.406s 30 1.03x
💻 Local Next.js (Turbopack) 1.752s (+0.5%) 2.010s (~) 0.013s (+3.4%) 2.026s (~) 0.274s 30 1.11x
🐘 Postgres Next.js (Turbopack) 2.044s (+15.7% 🔺) 2.508s (+24.7% 🔺) 0.004s (-18.2% 🟢) 2.534s (+25.0% 🔺) 0.490s 24 1.30x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 6.095s (-5.8% 🟢) 7.732s (+0.6%) 0.258s (+57.5% 🔺) 8.507s (+2.5%) 2.412s 8 1.00x
▲ Vercel Nitro 6.284s (+2.0%) 7.414s (-6.1% 🟢) 0.203s (+7.0% 🔺) 8.094s (-5.8% 🟢) 1.810s 8 1.03x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.785s (-1.0%) 1.068s (+1.9%) 0.000s (-74.6% 🟢) 1.078s (+1.0%) 0.293s 56 1.00x
🐘 Postgres Express 0.826s (+8.3% 🔺) 1.064s (+3.4%) 0.000s (+205.3% 🔺) 1.078s (+2.6%) 0.252s 57 1.05x
🐘 Postgres Next.js (Turbopack) 1.154s (+14.3% 🔺) 1.622s (+11.6% 🔺) 0.000s (+Infinity% 🔺) 1.645s (+12.6% 🔺) 0.490s 37 1.47x
💻 Local Express 1.395s (+1.1%) 2.014s (~) 0.000s (+16.7% 🔺) 2.016s (~) 0.621s 30 1.78x
💻 Local Nitro 1.407s (-0.8%) 2.014s (~) 0.000s (-20.0% 🟢) 2.016s (~) 0.609s 30 1.79x
💻 Local Next.js (Turbopack) 1.528s (+1.5%) 2.013s (~) 0.000s (-38.5% 🟢) 2.016s (~) 0.488s 30 1.95x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.788s (-37.8% 🟢) 4.075s (-29.9% 🟢) 0.000s (NaN%) 4.571s (-26.6% 🟢) 1.783s 14 1.00x
▲ Vercel Nitro 3.164s (-5.4% 🟢) 4.240s (-9.3% 🟢) 0.000s (+Infinity% 🔺) 4.702s (-9.1% 🟢) 1.539s 13 1.13x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Nitro

fan-out fan-in 10 streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.597s (-2.1%) 2.179s (+1.9%) 0.000s (NaN%) 2.186s (~) 0.590s 28 1.00x
🐘 Postgres Express 1.708s (+5.6% 🔺) 2.215s (+3.6%) 0.000s (+3.7%) 2.232s (+3.7%) 0.524s 27 1.07x
🐘 Postgres Next.js (Turbopack) 2.461s (+24.2% 🔺) 3.054s (+27.1% 🔺) 0.000s (+25.0% 🔺) 3.066s (+27.3% 🔺) 0.605s 20 1.54x
💻 Local Next.js (Turbopack) 3.090s (+2.7%) 3.604s (+2.2%) 0.001s (-3.7%) 3.618s (+2.5%) 0.528s 17 1.94x
💻 Local Nitro 3.131s (+1.7%) 3.901s (+3.3%) 0.001s (-11.1% 🟢) 3.905s (+3.3%) 0.774s 16 1.96x
💻 Local Express 3.170s (-1.1%) 3.961s (-1.7%) 0.001s (+19.3% 🔺) 3.967s (-1.6%) 0.796s 16 1.99x

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Nitro 4.270s (-4.4%) 5.381s (-12.5% 🟢) 0.000s (+Infinity% 🔺) 5.941s (-11.1% 🟢) 1.671s 11 1.00x
▲ Vercel Next.js (Turbopack) 4.353s (-20.0% 🟢) 5.908s (-13.8% 🟢) 0.000s (-100.0% 🟢) 6.385s (-12.4% 🟢) 2.032s 10 1.02x
▲ Vercel Express ⚠️ missing - - - - -

🔍 Observability: Nitro | Next.js (Turbopack)

Summary

Fastest Framework by World

Winner determined by most benchmark wins

World 🥇 Fastest Framework Wins
💻 Local Nitro 15/21
🐘 Postgres Nitro 17/21
▲ Vercel Nitro 12/21
Fastest World by Framework

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 13/21
Next.js (Turbopack) 🐘 Postgres 18/21
Nitro 🐘 Postgres 14/21
Column Definitions
  • Workflow Time: Runtime reported by workflow (completedAt - createdAt) - primary metric
  • TTFB: Time to First Byte - time from workflow start until first stream byte received (stream benchmarks only)
  • Slurp: Time from first byte to complete stream consumption (stream benchmarks only)
  • Wall Time: Total testbench time (trigger workflow + poll for result)
  • Overhead: Testbench overhead (Wall Time - Workflow Time)
  • Samples: Number of benchmark iterations run
  • vs Fastest: How much slower compared to the fastest configuration for this benchmark

Worlds:

  • 💻 Local: In-memory filesystem world (local development)
  • 🐘 Postgres: PostgreSQL database world (local development)
  • ▲ Vercel: Vercel production/preview deployment
  • 🌐 Turso: Community world (local development)
  • 🌐 MongoDB: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Jazz: Community world (local development)
  • 🌐 Redis: Community world (local development)
  • 🌐 Redis + BullMQ: Community world (local development)
  • 🌐 Cloudflare: Community world (local development)
  • 🌐 MySQL: Community world (local development)
  • 🌐 Azure: Community world (local development)
  • 🌐 NATS JetStream: Community world (local development)
  • 🌐 Upstash: Community world (local development)

📋 View full workflow run


Some benchmark jobs failed:

  • Local: success
  • Postgres: success
  • Vercel: failure

Check the workflow run for details.

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

⚠️ Results below are stale and not from the latest commit. This comment will be updated when CI completes on the latest run.

Tests are running...


_Started at: _


All tests passed

Summary

Passed Failed Skipped Total
✅ ▲ Vercel Production 1442 0 230 1672
✅ 💻 Local Development 1909 0 219 2128
✅ 📦 Local Production 1909 0 219 2128
✅ 🐘 Local Postgres 1895 0 233 2128
✅ 📋 Other 885 0 179 1064
Total 8040 0 1080 9120

Details by Category

✅ ▲ Vercel Production
App Passed Failed Skipped
✅ astro 125 0 27
✅ example 125 0 27
✅ express 125 0 27
✅ fastify 125 0 27
✅ hono 125 0 27
✅ nextjs-turbopack 149 0 3
✅ nextjs-webpack 149 0 3
✅ nitro 125 0 27
✅ nuxt 125 0 27
✅ sveltekit 144 0 8
✅ vite 125 0 27
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 152 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 152 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 127 0 25
✅ express-stable 127 0 25
✅ fastify-stable 127 0 25
✅ hono-stable 127 0 25
✅ nextjs-turbopack-canary 133 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 152 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 152 0 0
✅ nextjs-webpack-canary 133 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 152 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 152 0 0
✅ nitro-stable 127 0 25
✅ nuxt-stable 127 0 25
✅ sveltekit-stable 146 0 6
✅ vite-stable 127 0 25
✅ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 126 0 26
✅ express-stable 126 0 26
✅ fastify-stable 126 0 26
✅ hono-stable 126 0 26
✅ nextjs-turbopack-canary 132 0 20
✅ nextjs-turbopack-stable-lazy-discovery-disabled 151 0 1
✅ nextjs-turbopack-stable-lazy-discovery-enabled 151 0 1
✅ nextjs-webpack-canary 132 0 20
✅ nextjs-webpack-stable-lazy-discovery-disabled 151 0 1
✅ nextjs-webpack-stable-lazy-discovery-enabled 151 0 1
✅ nitro-stable 126 0 26
✅ nuxt-stable 126 0 26
✅ sveltekit-stable 145 0 7
✅ vite-stable 126 0 26
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 127 0 25
✅ e2e-local-dev-tanstack-start- 127 0 25
✅ e2e-local-postgres-nest-stable 126 0 26
✅ e2e-local-postgres-tanstack-start- 126 0 26
✅ e2e-local-prod-nest-stable 127 0 25
✅ e2e-local-prod-tanstack-start- 127 0 25
✅ e2e-vercel-prod-tanstack-start 125 0 27

📋 View full workflow run


Some E2E test jobs failed:

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

Check the workflow run for details.

Copilot AI left a comment

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.

Pull request overview

This PR adjusts start({ deploymentId: 'latest' }) behavior so it no longer throws in Worlds that don’t implement resolveLatestDeploymentId() (e.g. local dev and Postgres). Instead, it logs a warning and targets the current deployment, making 'latest' an intentional no-op outside atomic-deployment platforms like Vercel.

Changes:

  • Updated start() to resolve 'latest' when supported, otherwise warn + fall back to currentDeploymentId instead of throwing.
  • Reworked unit coverage to assert warn + fallback behavior, and added an e2e test ensuring non-Vercel worlds can start/complete runs using deploymentId: 'latest'.
  • Updated v4/v5 docs and added a changeset documenting the no-op-with-warning behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/core/src/runtime/start.ts Warn + fall back to current deployment when 'latest' is used in Worlds without resolveLatestDeploymentId().
packages/core/src/runtime/start.test.ts Replaces the previous “throws” expectation with a warn + fallback assertion (event payload + queue dispatch).
packages/core/e2e/e2e.test.ts Adds a non-Vercel-gated e2e test verifying 'latest' doesn’t break local/Postgres runs.
docs/content/docs/v5/api-reference/workflow-api/start.mdx Documents 'latest' being a no-op (with warning) outside atomic-deployment worlds.
docs/content/docs/v4/api-reference/workflow-api/start.mdx Same documentation update for v4 docs.
.changeset/deployment-id-latest-noop-non-vercel.md Patch changeset describing the behavior change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +518 to +522
it('should warn and fall back to the current deployment ID when "latest" is used with a World that does not implement resolveLatestDeploymentId', async () => {
const warnSpy = vi
.spyOn(runtimeLogger, 'warn')
.mockImplementation(() => {});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 17604c2. The block's afterEach now calls vi.restoreAllMocks() (in addition to vi.clearAllMocks()), so the runtimeLogger.warn spy is restored even if an assertion throws before the test's own cleanup. Dropped the manual warnSpy.mockRestore(), and the guard is reset in beforeEach so the warn path is exercisable regardless of test order.

Comment thread packages/core/src/runtime/start.ts Outdated
Comment on lines +207 to +213
runtimeLogger.warn(
"deploymentId: 'latest' has no effect in this world and was ignored. " +
'It is only supported by worlds with atomic deployments, such as Vercel. ' +
'The run will target the current deployment.',
{ currentDeploymentId }
);
deploymentId = currentDeploymentId;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call — done in 17604c2. The warning is now gated behind a once-per-process guard (hasWarnedLatestNoOp), mirroring the warnOnce pattern already used in constants.ts. Users still get the nudge that 'latest' is a no-op here, but a workflow that hardcodes 'latest' for Vercel won't flood a tight local/Postgres dev loop. Exposed _resetLatestNoOpWarnForTests() (@internal) so the warn path stays testable, and added a test asserting it fires exactly once across repeated 'latest' starts.

@TooTallNate TooTallNate left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approve — correct behavior change, and it quietly fixes a second bug too

Turning deploymentId: 'latest' from a hard throw into a warn-and-fall-back is the right call: a workflow that opts into 'latest' to target the newest Vercel deployment shouldn't be unrunnable in local dev or Postgres, where there's no deployment set to resolve between. The fix is minimal and the reasoning in both the code comment and the JSDoc is clear about why it's a no-op rather than just that it is.

What I verified:

  • WorkflowRuntimeError import is not orphaned — still used at 8 other sites in start.ts; runtimeLogger and currentDeploymentId are both already in scope above the check.
  • The fallback also fixes a downstream interaction the PR doesn't mention. Setting deploymentId = currentDeploymentId (not leaving it as the 'latest' sentinel) means the later if (deploymentId === currentDeploymentId) gate takes the same-deployment fast path — framing + compression enabled, no health-probe round-trip. That's exactly right for local/Postgres, where 'latest' semantically means "right here." Had it fallen through with the sentinel still set, it would have taken the cross-deployment branch and either probed a nonexistent target or disabled framing. Worth a sentence in the PR body, but the code does the correct thing.
  • The unit test is the right replacement — asserts the warning (message + currentDeploymentId context) and that the fallback lands on both payloads (run_created eventData and the queue dispatch's deploymentId), not just that it didn't throw. 27/27 pass locally; typecheck clean.
  • The e2e test is well-scoped: reuses addTenWorkflow (no new workbench files), correctly skipIf(WORKFLOW_VERCEL_ENV) so it exercises the real no-op on local/Postgres while leaving Vercel's actual resolve-API path alone, and asserts both the return value and the CLI-inspected run record. This is genuinely new coverage — 'latest' previously had no e2e exercise on non-Vercel worlds.
  • Docs (v4 + v5) accurately describe the no-op-with-warning behavior and the "still runs unchanged locally" implication. Changeset is a correctly-scoped patch on @workflow/core.

One small note (non-blocking)

The warning fires on every start({ deploymentId: 'latest' }) call in local dev — which, for a workflow that hardcodes 'latest' for its Vercel deployment, means every single local run logs it. That's arguably the intended nudge ("this option does nothing here"), but for a tight dev loop it could get noisy. Not worth gating or deduping for this PR; flagging only in case repeated-warning noise comes up — runtimeLogger.warn once-per-process would be a trivial follow-up if it does.

CI

The three red lanes are all unrelated to this change: E2E Windows Tests aborted in dev.test.ts on a "Next.js dev server unhealthy / Turbopack" startup failure (the new test never ran — the suite bailed before it), and Benchmark Vercel (express) + the E2E Required Check cascade are this cycle's known baseline flakes. The new test is gated off Vercel anyway. Nothing here implicates the PR.

LGTM.

…anup

Address PR review:
- Gate the 'latest'-has-no-effect warning behind a once-per-process guard
  (mirrors the warnOnce pattern in constants.ts) so a workflow that hardcodes
  'latest' for Vercel doesn't flood local/Postgres dev logs on every run.
  Exposes _resetLatestNoOpWarnForTests() (@internal) for unit tests.
- start.test.ts: reset the guard in beforeEach and restore spies in afterEach
  via vi.restoreAllMocks() so a throwing assertion can't leak the
  runtimeLogger.warn spy into later tests; drop the manual mockRestore().
- Add a test asserting the warning fires exactly once across repeated
  'latest' starts while every run still falls back to the current deployment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

4 participants