Skip to content

Expose conflicting run id on hook conflicts#2012

Merged
pranaygp merged 6 commits into
mainfrom
pranaygp/codex/hook-conflict-run-id
May 19, 2026
Merged

Expose conflicting run id on hook conflicts#2012
pranaygp merged 6 commits into
mainfrom
pranaygp/codex/hook-conflict-run-id

Conversation

@pranaygp
Copy link
Copy Markdown
Contributor

@pranaygp pranaygp commented May 18, 2026

Summary

  • add conflictingRunId to hook_conflict events and HookConflictError
  • populate the active hook owner run id from local and postgres worlds
  • preserve hook conflict metadata through serialization and document resumeHook / getRun idempotency delegation patterns

Related

  • Vercel-hosted world/server support: vercel/workflow-server#428 (merged)

The two PRs are compatible in either merge order: this SDK PR keeps conflictingRunId optional for old persisted events / older worlds, and the server PR only adds an extra event data field that older clients should ignore.

Testing

  • pnpm install --frozen-lockfile
  • pnpm --filter @workflow/errors --filter @workflow/world --filter @workflow/utils --filter @workflow/serde build
  • pnpm --filter @workflow/world-local --filter @workflow/world-vercel --filter @workflow/world-postgres build
  • pnpm --filter @workflow/core build
  • pnpm --filter @workflow/docs-typecheck build
  • pnpm vitest run packages/core/src/workflow/hook.test.ts packages/core/src/workflow.test.ts packages/core/src/serialization.test.ts packages/world-local/src/storage.test.ts
  • pnpm vitest run packages/world-postgres/test/storage.test.ts blocked locally: Testcontainers could not find a working container runtime strategy
  • pnpm --filter docs build blocked locally by existing prerender/TSDoc issue on /docs/api-reference/workflow/create-hook: Your type is resolved as "any"

Note: local commands warn because this machine is on Node 25.2.1 while the repo engine allows Node 18/20/22/24.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 18, 2026

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 May 19, 2026 0:18am
example-nextjs-workflow-webpack Ready Ready Preview, Comment May 19, 2026 0:18am
example-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-astro-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-express-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-fastify-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-hono-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-nitro-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-nuxt-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-sveltekit-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-tanstack-start-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workbench-vite-workflow Ready Ready Preview, Comment May 19, 2026 0:18am
workflow-docs Ready Ready Preview, 💬 1 unresolved, Open in v0 May 19, 2026 0:18am
workflow-swc-playground Ready Ready Preview, Comment May 19, 2026 0:18am
workflow-tarballs Ready Ready Preview, Comment May 19, 2026 0:18am
workflow-web Ready Ready Preview, Comment May 19, 2026 0:18am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 18, 2026

🦋 Changeset detected

Latest commit: 6ba9a17

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

This PR includes changesets to release 23 packages
Name Type
@workflow/core Patch
@workflow/errors 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 Patch
@workflow/world-testing Patch
tarballs Patch
@workflow/world-vercel Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/nuxt Patch
@workflow/ai 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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

🧪 E2E Test Results

Some tests failed

Summary

Passed Failed Skipped Total
❌ ▲ Vercel Production 1195 5 219 1419
✅ 💻 Local Development 1587 0 219 1806
✅ 📦 Local Production 1587 0 219 1806
❌ 🐘 Local Postgres 1583 4 219 1806
✅ 🪟 Windows 129 0 0 129
✅ 📋 Other 727 0 176 903
Total 6808 9 1052 7869

❌ Failed Tests

▲ Vercel Production (5 failed)

astro (2 failed):

  • error handling not registered StepNotRegisteredError fails the run when not caught in workflow
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step

express (1 failed):

  • error handling not registered StepNotRegisteredError fails the step but workflow can catch it

fastify (1 failed):

  • outputStreamWorkflow no startIndex (reads all chunks)

hono (1 failed):

  • AbortController abortParallelWorkflow: abort cancels all parallel steps
🐘 Local Postgres (4 failed)

nextjs-turbopack-stable-lazy-discovery-disabled (1 failed):

  • addTenWorkflow | wrun_01KRYSE4HYJ3W7PPATXERM9366

nextjs-turbopack-stable-lazy-discovery-enabled (1 failed):

  • addTenWorkflow | wrun_01KRYSE4HYJ3W7PPATXERM9366

nextjs-webpack-stable-lazy-discovery-disabled (1 failed):

  • addTenWorkflow | wrun_01KRYSE4HYJ3W7PPATXERM9366

nextjs-webpack-stable-lazy-discovery-enabled (1 failed):

  • DurableAgent e2e core basic text response

Details by Category

❌ ▲ Vercel Production
App Passed Failed Skipped
❌ astro 101 2 26
✅ example 103 0 26
❌ express 102 1 26
❌ fastify 102 1 26
❌ hono 102 1 26
✅ nextjs-turbopack 127 0 2
✅ nextjs-webpack 127 0 2
✅ nitro 103 0 26
✅ nuxt 103 0 26
✅ sveltekit 122 0 7
✅ vite 103 0 26
✅ 💻 Local Development
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 129 0 0
✅ nextjs-webpack-canary 110 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 129 0 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
✅ 📦 Local Production
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
✅ nextjs-turbopack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-turbopack-stable-lazy-discovery-enabled 129 0 0
✅ nextjs-webpack-canary 110 0 19
✅ nextjs-webpack-stable-lazy-discovery-disabled 129 0 0
✅ nextjs-webpack-stable-lazy-discovery-enabled 129 0 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
❌ 🐘 Local Postgres
App Passed Failed Skipped
✅ astro-stable 104 0 25
✅ express-stable 104 0 25
✅ fastify-stable 104 0 25
✅ hono-stable 104 0 25
✅ nextjs-turbopack-canary 110 0 19
❌ nextjs-turbopack-stable-lazy-discovery-disabled 128 1 0
❌ nextjs-turbopack-stable-lazy-discovery-enabled 128 1 0
✅ nextjs-webpack-canary 110 0 19
❌ nextjs-webpack-stable-lazy-discovery-disabled 128 1 0
❌ nextjs-webpack-stable-lazy-discovery-enabled 128 1 0
✅ nitro-stable 104 0 25
✅ nuxt-stable 104 0 25
✅ sveltekit-stable 123 0 6
✅ vite-stable 104 0 25
✅ 🪟 Windows
App Passed Failed Skipped
✅ nextjs-turbopack 129 0 0
✅ 📋 Other
App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 104 0 25
✅ e2e-local-dev-tanstack-start- 104 0 25
✅ e2e-local-postgres-nest-stable 104 0 25
✅ e2e-local-postgres-tanstack-start- 104 0 25
✅ e2e-local-prod-nest-stable 104 0 25
✅ e2e-local-prod-tanstack-start- 104 0 25
✅ e2e-vercel-prod-tanstack-start 103 0 26

📋 View full workflow run


Some E2E test jobs failed:

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

Check the workflow run for details.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

📊 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 🥇 Express 0.031s (-30.7% 🟢) 1.017s (+1.2%) 0.986s 10 1.00x
💻 Local Nitro 0.032s (-26.0% 🟢) 1.006s (~) 0.974s 10 1.04x
🐘 Postgres Nitro 0.053s (-44.3% 🟢) 1.012s (-2.9%) 0.959s 10 1.73x
🐘 Postgres Express 0.054s (-6.7% 🟢) 1.012s (~) 0.958s 10 1.76x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 0.265s (+5.2% 🔺) 2.135s (-8.5% 🟢) 1.870s 10 1.00x
▲ Vercel Express 0.277s (+17.5% 🔺) 2.139s (~) 1.862s 10 1.04x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 1 step

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 1.071s (-4.9%) 2.006s (~) 0.936s 10 1.00x
💻 Local Nitro 1.077s (-4.8%) 2.006s (~) 0.929s 10 1.01x
🐘 Postgres Nitro 1.080s (-5.2% 🟢) 2.008s (~) 0.928s 10 1.01x
🐘 Postgres Express 1.089s (-5.0% 🟢) 2.010s (~) 0.921s 10 1.02x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 1.658s (-18.5% 🟢) 3.304s (-13.7% 🟢) 1.646s 10 1.00x
▲ Vercel Express 1.868s (~) 3.864s (+1.5%) 1.996s 10 1.13x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 10 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 10.409s (-4.7%) 11.021s (~) 0.612s 3 1.00x
💻 Local Nitro 10.418s (-4.8%) 11.022s (~) 0.604s 3 1.00x
🐘 Postgres Nitro 10.420s (-4.1%) 11.017s (~) 0.597s 3 1.00x
🐘 Postgres Express 10.427s (-4.9%) 11.017s (~) 0.590s 3 1.00x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 14.201s (-18.0% 🟢) 15.904s (-18.0% 🟢) 1.703s 2 1.00x
▲ Vercel Express 14.543s (-14.4% 🟢) 16.833s (-15.9% 🟢) 2.290s 2 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 25 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 13.436s (-10.2% 🟢) 14.026s (-6.7% 🟢) 0.590s 5 1.00x
🐘 Postgres Nitro 13.488s (-7.6% 🟢) 14.019s (-6.7% 🟢) 0.531s 5 1.00x
🐘 Postgres Express 13.493s (-7.5% 🟢) 14.016s (-6.7% 🟢) 0.522s 5 1.00x
💻 Local Nitro 13.556s (-10.0% 🟢) 14.026s (-12.5% 🟢) 0.470s 5 1.01x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 22.226s (-55.8% 🟢) 23.977s (-54.4% 🟢) 1.751s 3 1.00x
▲ Vercel Next.js (Turbopack) 22.640s (-56.9% 🟢) 24.249s (-55.6% 🟢) 1.610s 3 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 50 sequential steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
💻 Local 🥇 Express 11.915s (-28.2% 🟢) 12.021s (-29.4% 🟢) 0.106s 8 1.00x
🐘 Postgres Nitro 11.964s (-14.3% 🟢) 12.142s (-15.1% 🟢) 0.178s 8 1.00x
🐘 Postgres Express 11.998s (-14.3% 🟢) 12.267s (-15.9% 🟢) 0.269s 8 1.01x
💻 Local Nitro 12.081s (-28.0% 🟢) 12.649s (-25.7% 🟢) 0.567s 8 1.01x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 36.077s (-90.8% 🟢) 37.371s (-90.5% 🟢) 1.294s 3 1.00x
▲ Vercel Express 36.866s (-69.6% 🟢) 39.044s (-68.4% 🟢) 2.178s 3 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

Promise.all with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.137s (-9.8% 🟢) 2.007s (~) 0.871s 15 1.00x
🐘 Postgres Nitro 1.150s (-9.8% 🟢) 2.008s (~) 0.858s 15 1.01x
💻 Local Express 1.176s (-21.0% 🟢) 2.006s (~) 0.830s 15 1.03x
💻 Local Nitro 1.234s (-24.4% 🟢) 2.008s (-3.2%) 0.774s 15 1.09x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.008s (+5.2% 🔺) 4.701s (+1.7%) 1.693s 7 1.00x
▲ Vercel Next.js (Turbopack) 3.241s (-4.6%) 4.497s (-8.8% 🟢) 1.256s 7 1.08x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.all with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.198s (-49.0% 🟢) 2.007s (-33.3% 🟢) 0.808s 15 1.00x
🐘 Postgres Express 1.208s (-48.8% 🟢) 2.008s (-33.3% 🟢) 0.800s 15 1.01x
💻 Local Express 1.752s (-40.7% 🟢) 2.005s (-41.9% 🟢) 0.253s 15 1.46x
💻 Local Nitro 1.844s (-41.3% 🟢) 2.074s (-46.6% 🟢) 0.231s 15 1.54x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.527s (-2.5%) 5.269s (+3.1%) 1.741s 6 1.00x
▲ Vercel Next.js (Turbopack) 3.604s (-49.2% 🟢) 5.070s (-43.1% 🟢) 1.466s 6 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.all with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.315s (-62.3% 🟢) 2.008s (-49.9% 🟢) 0.693s 15 1.00x
🐘 Postgres Nitro 1.333s (-61.7% 🟢) 2.009s (-49.9% 🟢) 0.676s 15 1.01x
💻 Local Express 5.188s (-37.8% 🟢) 5.512s (-38.9% 🟢) 0.325s 6 3.94x
💻 Local Nitro 5.521s (-33.9% 🟢) 6.018s (-33.3% 🟢) 0.497s 6 4.20x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 4.839s (+14.1% 🔺) 6.254s (+2.1%) 1.416s 5 1.00x
▲ Vercel Next.js (Turbopack) 6.880s (-22.8% 🟢) 8.243s (-24.8% 🟢) 1.362s 4 1.42x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.race with 10 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.145s (-8.9% 🟢) 2.008s (~) 0.863s 15 1.00x
🐘 Postgres Nitro 1.149s (-8.6% 🟢) 2.010s (~) 0.861s 15 1.00x
💻 Local Express 1.373s (-27.5% 🟢) 2.006s (-15.1% 🟢) 0.633s 15 1.20x
💻 Local Nitro 1.449s (-22.4% 🟢) 2.006s (-14.3% 🟢) 0.558s 15 1.26x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.653s (-9.5% 🟢) 4.281s (-7.8% 🟢) 1.628s 8 1.00x
▲ Vercel Express 2.725s (+5.6% 🔺) 4.383s (+0.8%) 1.658s 7 1.03x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

Promise.race with 25 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.203s (-48.6% 🟢) 2.009s (-33.3% 🟢) 0.806s 15 1.00x
🐘 Postgres Nitro 1.208s (-48.4% 🟢) 2.009s (-33.2% 🟢) 0.802s 15 1.00x
💻 Local Express 2.013s (-35.7% 🟢) 2.508s (-33.3% 🟢) 0.495s 12 1.67x
💻 Local Nitro 2.220s (-27.6% 🟢) 2.675s (-31.2% 🟢) 0.455s 12 1.85x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.713s (+16.3% 🔺) 5.387s (+12.4% 🔺) 1.674s 6 1.00x
▲ Vercel Next.js (Turbopack) 4.008s (+27.6% 🔺) 5.400s (+19.4% 🔺) 1.392s 6 1.08x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

Promise.race with 50 concurrent steps

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.344s (-61.4% 🟢) 2.007s (-49.9% 🟢) 0.663s 15 1.00x
🐘 Postgres Express 1.344s (-61.6% 🟢) 2.007s (-50.0% 🟢) 0.663s 15 1.00x
💻 Local Express 6.471s (-26.5% 🟢) 7.016s (-24.3% 🟢) 0.545s 5 4.81x
💻 Local Nitro 7.732s (-15.4% 🟢) 8.271s (-17.5% 🟢) 0.539s 4 5.75x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.579s (-13.1% 🟢) 7.644s (-6.5% 🟢) 2.065s 4 1.00x
▲ Vercel Next.js (Turbopack) 5.962s (-11.8% 🟢) 7.118s (-16.7% 🟢) 1.156s 5 1.07x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 10 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.435s (-46.9% 🟢) 1.007s (~) 0.571s 60 1.00x
🐘 Postgres Express 0.474s (-43.5% 🟢) 1.024s (~) 0.550s 59 1.09x
💻 Local Express 0.507s (-48.4% 🟢) 1.021s (-5.1% 🟢) 0.513s 60 1.17x
💻 Local Nitro 0.521s (-46.8% 🟢) 1.006s (-8.1% 🟢) 0.484s 60 1.20x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.062s (-65.1% 🟢) 6.673s (-58.5% 🟢) 1.611s 10 1.00x
▲ Vercel Express 5.152s (-72.9% 🟢) 7.001s (-67.2% 🟢) 1.848s 9 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 25 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.042s (-45.9% 🟢) 1.575s (-25.0% 🟢) 0.533s 58 1.00x
🐘 Postgres Express 1.069s (-45.9% 🟢) 1.808s (-19.9% 🟢) 0.738s 50 1.03x
💻 Local Express 1.176s (-61.0% 🟢) 2.005s (-44.1% 🟢) 0.829s 45 1.13x
💻 Local Nitro 1.261s (-58.5% 🟢) 2.006s (-46.6% 🟢) 0.745s 45 1.21x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 15.556s (-54.9% 🟢) 17.392s (-52.8% 🟢) 1.836s 6 1.00x
▲ Vercel Next.js (Turbopack) 17.214s (-65.4% 🟢) 18.835s (-63.6% 🟢) 1.621s 5 1.11x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | Next.js (Turbopack)

workflow with 50 sequential data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 2.097s (-48.9% 🟢) 2.582s (-43.9% 🟢) 0.485s 47 1.00x
🐘 Postgres Express 2.121s (-46.9% 🟢) 2.697s (-38.3% 🟢) 0.576s 45 1.01x
💻 Local Express 2.668s (-71.0% 🟢) 3.032s (-69.7% 🟢) 0.364s 40 1.27x
💻 Local Nitro 2.855s (-69.3% 🟢) 3.245s (-67.6% 🟢) 0.390s 38 1.36x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 42.876s (-60.0% 🟢) 44.389s (-59.2% 🟢) 1.513s 3 1.00x
▲ Vercel Express 43.850s (-66.3% 🟢) 45.245s (-65.8% 🟢) 1.395s 3 1.02x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 10 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 0.176s (-37.7% 🟢) 1.006s (~) 0.830s 60 1.00x
🐘 Postgres Nitro 0.178s (-37.2% 🟢) 1.006s (~) 0.828s 60 1.01x
💻 Local Express 0.413s (-26.3% 🟢) 1.004s (~) 0.591s 60 2.35x
💻 Local Nitro 0.487s (-19.5% 🟢) 1.005s (-1.6%) 0.518s 60 2.77x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 2.197s (+8.6% 🔺) 3.747s (-1.2%) 1.550s 17 1.00x
▲ Vercel Express 2.225s (+13.8% 🔺) 3.824s (+5.1% 🔺) 1.599s 16 1.01x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Next.js (Turbopack) | Express

workflow with 25 concurrent data payload steps (10KB)

💻 Local Development

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.295s (-40.6% 🟢) 1.006s (~) 0.711s 90 1.00x
🐘 Postgres Express 0.303s (-40.7% 🟢) 1.006s (~) 0.704s 90 1.03x
💻 Local Express 2.194s (-12.7% 🟢) 2.821s (-6.3% 🟢) 0.627s 32 7.44x
💻 Local Nitro 2.266s (-10.7% 🟢) 3.009s (~) 0.743s 30 7.68x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 7.945s (+160.8% 🔺) 9.389s (+95.3% 🔺) 1.443s 10 1.00x
▲ Vercel Next.js (Turbopack) 9.213s (+160.6% 🔺) 10.791s (+107.8% 🔺) 1.578s 9 1.16x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | 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.613s (-22.5% 🟢) 1.006s (~) 0.393s 120 1.00x
🐘 Postgres Express 0.638s (-22.1% 🟢) 1.006s (-1.1%) 0.369s 120 1.04x
💻 Local Express 9.921s (-11.3% 🟢) 10.531s (-11.8% 🟢) 0.609s 12 16.19x
💻 Local Nitro 11.730s (+4.8%) 12.134s (+4.0%) 0.404s 10 19.14x
💻 Local Next.js (Turbopack) ⚠️ missing - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - -

▲ Production (Vercel)

World Framework Workflow Time Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 23.134s (+211.8% 🔺) 24.850s (+168.8% 🔺) 1.716s 5 1.00x
▲ Vercel Next.js (Turbopack) 25.312s (+145.1% 🔺) 26.959s (+119.4% 🔺) 1.647s 5 1.09x
▲ Vercel Nitro ⚠️ missing - - - -

🔍 Observability: Express | 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 🥇 Express 1.136s (+470.5% 🔺) 2.005s (+99.6% 🔺) 0.012s (+1.7%) 2.019s (+98.4% 🔺) 0.883s 10 1.00x
🐘 Postgres Nitro 1.141s (+456.5% 🔺) 2.000s (+100.1% 🔺) 0.001s (-6.7% 🟢) 2.010s (+98.7% 🔺) 0.869s 10 1.00x
🐘 Postgres Express 1.148s (+459.6% 🔺) 1.998s (+100.1% 🔺) 0.002s (~) 2.011s (+98.8% 🔺) 0.863s 10 1.01x
💻 Local Nitro 1.161s (+443.5% 🔺) 2.008s (+99.9% 🔺) 0.021s (+65.6% 🔺) 2.031s (+99.4% 🔺) 0.870s 10 1.02x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 2.357s (-5.9% 🟢) 3.603s (-11.9% 🟢) 2.430s (+152.9% 🔺) 6.484s (+16.0% 🔺) 4.127s 10 1.00x
▲ Vercel Next.js (Turbopack) 2.671s (-61.0% 🟢) 3.586s (-58.5% 🟢) 2.323s (+267.7% 🔺) 6.331s (-35.3% 🟢) 3.660s 10 1.13x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

stream pipeline with 5 transform steps (1MB)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 1.505s (+141.1% 🔺) 2.002s (+98.8% 🔺) 0.004s (-9.7% 🟢) 2.024s (+97.9% 🔺) 0.519s 30 1.00x
🐘 Postgres Express 1.548s (+145.7% 🔺) 2.003s (+99.1% 🔺) 0.004s (+5.3% 🔺) 2.025s (+98.0% 🔺) 0.478s 30 1.03x
💻 Local Nitro 1.595s (+90.2% 🔺) 2.013s (+98.9% 🔺) 0.013s (+41.6% 🔺) 2.029s (+81.8% 🔺) 0.434s 30 1.06x
💻 Local Express 1.703s (+125.0% 🔺) 2.009s (+95.3% 🔺) 0.009s (+0.5%) 2.199s (+111.5% 🔺) 0.496s 28 1.13x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 5.907s (-9.2% 🟢) 7.085s (-11.5% 🟢) 0.186s (-54.5% 🟢) 7.771s (-12.0% 🟢) 1.865s 8 1.00x
▲ Vercel Next.js (Turbopack) 6.066s (-64.1% 🟢) 7.109s (-61.0% 🟢) 0.200s (-5.4% 🟢) 7.688s (-59.4% 🟢) 1.622s 8 1.03x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

10 parallel streams (1MB each)

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Nitro 0.670s (-30.9% 🟢) 0.993s (-20.4% 🟢) 0.000s (+62.7% 🔺) 1.025s (-18.5% 🟢) 0.355s 59 1.00x
🐘 Postgres Express 0.694s (-27.7% 🟢) 1.068s (-16.4% 🟢) 0.000s (-59.6% 🟢) 1.077s (-17.6% 🟢) 0.382s 57 1.04x
💻 Local Express 1.305s (+6.5% 🔺) 2.015s (~) 0.000s (-20.0% 🟢) 2.017s (~) 0.712s 30 1.95x
💻 Local Nitro 1.443s (+18.0% 🔺) 2.016s (~) 0.000s (+233.3% 🔺) 2.019s (~) 0.576s 30 2.15x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Express 3.574s (-4.5%) 4.739s (-7.1% 🟢) 0.001s (+266.7% 🔺) 5.181s (-6.3% 🟢) 1.607s 12 1.00x
▲ Vercel Next.js (Turbopack) 3.692s (-63.7% 🟢) 4.654s (-59.6% 🟢) 0.000s (NaN%) 5.012s (-58.4% 🟢) 1.320s 13 1.03x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Express | Next.js (Turbopack)

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

💻 Local Development

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
🐘 Postgres 🥇 Express 1.308s (-26.2% 🟢) 1.996s (-8.4% 🟢) 0.000s (+Infinity% 🔺) 2.023s (-8.0% 🟢) 0.715s 30 1.00x
🐘 Postgres Nitro 1.345s (-24.9% 🟢) 2.096s (-2.1%) 0.000s (-3.4%) 2.122s (-2.4%) 0.777s 29 1.03x
💻 Local Express 3.078s (-11.2% 🟢) 3.736s (-7.4% 🟢) 0.001s (-19.1% 🟢) 3.738s (-7.4% 🟢) 0.661s 17 2.35x
💻 Local Nitro 3.326s (-1.8%) 3.970s (-1.5%) 0.001s (+64.1% 🔺) 3.974s (-1.6%) 0.647s 16 2.54x
💻 Local Next.js (Turbopack) ⚠️ missing - - - - -
🐘 Postgres Next.js (Turbopack) ⚠️ missing - - - - -

▲ Production (Vercel)

World Framework Workflow Time TTFB Slurp Wall Time Overhead Samples vs Fastest
▲ Vercel 🥇 Next.js (Turbopack) 5.503s (-2.0%) 6.507s (-6.8% 🟢) 0.000s (-11.1% 🟢) 6.851s (-9.1% 🟢) 1.348s 9 1.00x
▲ Vercel Express 5.650s (+23.2% 🔺) 7.075s (+17.5% 🔺) 0.000s (NaN%) 7.509s (+16.3% 🔺) 1.859s 9 1.03x
▲ Vercel Nitro ⚠️ missing - - - - -

🔍 Observability: Next.js (Turbopack) | Express

Summary

Fastest Framework by World

Winner determined by most benchmark wins

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

Winner determined by most benchmark wins

Framework 🥇 Fastest World Wins
Express 🐘 Postgres 15/21
Next.js (Turbopack) ▲ Vercel 21/21
Nitro 🐘 Postgres 18/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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 enhances hook conflict diagnostics by surfacing the active (conflicting) workflow run ID on hook_conflict events and propagating it through HookConflictError, including across serialization boundaries. This improves idempotency/delegation flows by enabling callers to directly target the owning run.

Changes:

  • Extend hook_conflict event data (schema + local/postgres worlds) to optionally include eventData.conflictingRunId.
  • Add conflictingRunId to HookConflictError, propagate it from events, and support cross-realm identity + dedicated (de)serialization.
  • Update tests, e2e assertions, and docs/examples to reflect the new conflict metadata and delegation patterns.

Reviewed changes

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

Show a summary per file
File Description
packages/world/src/events.ts Extend hook_conflict event schema to include optional conflictingRunId.
packages/world-postgres/src/storage.ts Populate conflictingRunId on hook_conflict from the existing hook’s runId.
packages/world-postgres/test/storage.test.ts Assert postgres hook_conflict events include conflictingRunId.
packages/world-local/src/storage/events-storage.ts Read existing token claim to attach conflictingRunId to local hook_conflict events.
packages/world-local/src/storage.test.ts Assert local hook_conflict events include conflictingRunId in multiple scenarios.
packages/errors/src/index.ts Add HookConflictError.conflictingRunId, improve cross-realm class registration, and include run info in message.
packages/core/src/workflow/hook.ts Thread conflictingRunId from hook_conflict event into HookConflictError.
packages/core/src/workflow/hook.test.ts Validate HookConflictError carries token + conflictingRunId.
packages/core/src/workflow.test.ts Assert conflictingRunId propagates through runWorkflow conflict handling.
packages/core/src/serialization/types.ts Define dedicated serialized shape for HookConflictError (incl. optional conflictingRunId).
packages/core/src/serialization/reducers/common.ts Add reducer/reviver for HookConflictError (dedicated key + cross-realm ctor lookup).
packages/core/src/serialization.test.ts Add round-trip + reducer-key tests for HookConflictError.
packages/core/e2e/e2e.test.ts Validate e2e conflict cause is HookConflictError and includes conflictingRunId.
docs/content/docs/v5/how-it-works/event-sourcing.mdx Document run-id metadata on hook conflicts.
docs/content/docs/v5/errors/hook-conflict.mdx Document conflictingRunId and delegation pattern via resumeHook/getRun.
docs/content/docs/v5/deploying/building-a-world.mdx Instruct world implementers to include eventData.conflictingRunId on conflicts.
docs/content/docs/v4/how-it-works/event-sourcing.mdx Same documentation updates for v4.
docs/content/docs/v4/errors/hook-conflict.mdx Same documentation updates for v4.
docs/content/docs/v4/deploying/building-a-world.mdx Same world-implementer guidance for v4.
.changeset/bright-hooks-share.md Release note for exposing the active run ID on hook token conflicts.
Comments suppressed due to low confidence (2)

docs/content/docs/v5/how-it-works/event-sourcing.mdx:192

  • The table entry says hook_conflict “contains ... the active hook owner's run ID”, but the SDK currently treats eventData.conflictingRunId as optional for backward compatibility. Consider noting that it’s included when available / for newer Worlds.
| Event | Description |
|-------|-------------|
| `hook_created` | Creates a new hook in `active` state. Contains the hook token and optional metadata. |
| `hook_conflict` | Records that hook creation failed because the token is already in use by another active hook. Contains the token and the active hook owner's run ID. The hook is not created, and awaiting the hook will reject with a `HookConflictError`. |
| `hook_received` | Records that a payload was delivered to the hook. The hook remains `active` and can receive more payloads. |

docs/content/docs/v4/how-it-works/event-sourcing.mdx:192

  • The table entry says hook_conflict “contains ... the active hook owner's run ID”, but the SDK currently treats eventData.conflictingRunId as optional for backward compatibility. Consider noting that it’s included when available / for newer Worlds.
| Event | Description |
|-------|-------------|
| `hook_created` | Creates a new hook in `active` state. Contains the hook token and optional metadata. |
| `hook_conflict` | Records that hook creation failed because the token is already in use by another active hook. Contains the token and the active hook owner's run ID. The hook is not created, and awaiting the hook will reject with a `HookConflictError`. |
| `hook_received` | Records that a payload was delivered to the hook. The hook remains `active` and can receive more payloads. |

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

Comment on lines +887 to +890
const existingClaim = await readJSON(
constraintPath,
HookTokenClaimSchema
);
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.

Updated world-local to tolerate malformed or schema-mismatched token-claim files by emitting hook_conflict without conflictingRunId, and added a regression test for that fallback.

Comment on lines +508 to +514
constructor(token: string, conflictingRunId?: string) {
super(
`Hook token "${token}" is already in use by another workflow${conflictingRunId ? ` run "${conflictingRunId}"` : ''}`,
{
slug: ERROR_SLUGS.HOOK_CONFLICT,
}
);
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.

Updated the message to use another workflow (run "<id>") when conflictingRunId is present.

Unlike other entities, hooks don't have a `status` field—the states above are conceptual. An "active" hook is one that exists in storage, while "disposed" means the hook has been deleted. When a `hook_disposed` event is created, the hook record is removed rather than updated.

While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token that is already in use by another active hook, a `hook_conflict` event is recorded instead of `hook_created`. This causes the hook's promise to reject with a `HookConflictError`, which you can detect with `HookConflictError.is(error)`. See the [hook-conflict error](/docs/errors/hook-conflict) documentation for more details.
While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token that is already in use by another active hook, a `hook_conflict` event is recorded instead of `hook_created`. The event includes the token and the run ID that currently owns it. This causes the hook's promise to reject with a `HookConflictError`, which you can detect with `HookConflictError.is(error)`. See the [hook-conflict error](/docs/errors/hook-conflict) documentation for more details.
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.

Updated the v5 event-sourcing docs in both the lifecycle text and event table to say current worlds include the owner run ID, while older persisted events/world implementations may only include the token.

Comment on lines +76 to 79
## Handling Hook Conflicts

When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. You can catch this error to handle the conflict gracefully:
When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. The error exposes the token that conflicted and the run ID that currently owns it:

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.

Updated the v5 docs to call out that conflictingRunId is still optional for older persisted events/world implementations, and guarded the example before using it for delegation.

Unlike other entities, hooks don't have a `status` field—the states above are conceptual. An "active" hook is one that exists in storage, while "disposed" means the hook has been deleted. When a `hook_disposed` event is created, the hook record is removed rather than updated.

While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token that is already in use by another active hook, a `hook_conflict` event is recorded instead of `hook_created`. This causes the hook's promise to reject with a `HookConflictError`, which you can detect with `HookConflictError.is(error)`. See the [hook-conflict error](/docs/errors/hook-conflict) documentation for more details.
While a hook is active, its token is reserved and cannot be used by other workflows. If a workflow attempts to create a hook with a token that is already in use by another active hook, a `hook_conflict` event is recorded instead of `hook_created`. The event includes the token and the run ID that currently owns it. This causes the hook's promise to reject with a `HookConflictError`, which you can detect with `HookConflictError.is(error)`. See the [hook-conflict error](/docs/errors/hook-conflict) documentation for more details.
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.

Updated the v4 event-sourcing docs in both the lifecycle text and event table to say current worlds include the owner run ID, while older persisted events/world implementations may only include the token.

Comment on lines +76 to 79
## Handling Hook Conflicts

When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. You can catch this error to handle the conflict gracefully:
When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. The error exposes the token that conflicted and the run ID that currently owns it:

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.

Updated the v4 docs to call out that conflictingRunId is still optional for older persisted events/world implementations, and guarded the example before using it for delegation.

…hook-conflict-run-id

* origin-https/main:
  Add workflow versioning docs (#2010)
  Hide flaky worlds indicators (#2000)
@github-actions
Copy link
Copy Markdown
Contributor

Backport PR opened against stable: #2016. Merge conflicts were resolved by AI — please review carefully.

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.

3 participants