Skip to content

[benchmarks] Log the run id and Datadog trace for each sequential-steps run - #3248

Open
shalabhc wants to merge 4 commits into
mainfrom
shalabhc/bench-histogram-run-trace-links
Open

[benchmarks] Log the run id and Datadog trace for each sequential-steps run#3248
shalabhc wants to merge 4 commits into
mainfrom
shalabhc/bench-histogram-run-trace-links

Conversation

@shalabhc

@shalabhc shalabhc commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Logs the run id and Datadog APM links for each sequential-steps benchmark iteration, in the benchmark job's own output:

[bench] 1020 steps run wrun_41KY… — trace https://app.datadoghq.com/apm/trace/6f1a… — spans https://app.datadoghq.com/apm/traces?query=%40workflow.run.id%3Awrun_41KY…

Follow-up to #3213 (which added the STSO histograms). Uses the run-id/trace capture prototyped on the WIP variance branch, #3107.

Why

The 📈 STSO distribution section shows the shape of the sequential-steps run but not which run produced it. When a bucket looks wrong, the next step is always the same manual hunt: find the run by deployment id + time window, then find its trace. This puts both in the log, next to the run that produced them.

These are debugging aids rather than part of the benchmark's reported result, so they go in the job output rather than the PR comment body. That also covers two cases a comment can't: a local pnpm bench, and a job that fails before the comment step runs.

What

  • workbench/nextjs-turbopack/app/api/bench/route.ts — returns traceId from the span @vercel/otel opened for the trigger request. @opentelemetry/api was already a dependency; no lockfile change.
  • packages/core/e2e/benchmark.test.ts — threads traceId through triggerBenchRunrunSequentialIteration, and logs one line per iteration as soon as the scenario completes.

A deployment built before the route reported a trace id logs the run id and span search, with no trace permalink.

Why two links

This deployment runs the default WORKFLOW_TRACE_MODE=linked — nothing in the workbench or benchmarks.yml sets the mode. Under linked, each workflow/step invocation is its own trace root, and the trigger's trace holds only workflow.start plus span links out to those roots. So the trace permalink is an entry point to the run (one hop through the links, which Datadog renders), not a single trace containing every step's spans.

The @workflow.run.id:<runId> span search lands directly on the run's execution spans instead, which is where an STSO investigation actually goes. It depends on workflow.run.id being an indexed span tag in the org, so it's logged alongside the permalink rather than replacing it — still to be confirmed against a real run.

Notes

The comment renderer is untouched, and the result artifact gains no new fields — the run identities are logged, not serialized.

One thing this deliberately drops relative to putting the line in the comment: there's no link to the main baseline's run. Which run produced the baseline histogram is only knowable at comment-render time, where the two artifacts are matched up; the benchmark job only knows about its own run.

Empty changeset — no package behavior changes.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jul 31, 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 Jul 31, 2026 11:06pm
example-nextjs-workflow-webpack Ready Ready Preview Jul 31, 2026 11:06pm
example-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-astro-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-express-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-fastify-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-hono-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-nestjs-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-nitro-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-nuxt-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-sveltekit-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-tanstack-start-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workbench-vite-workflow Ready Ready Preview Jul 31, 2026 11:06pm
workflow-docs Ready Ready Preview, v0 Jul 31, 2026 11:06pm
workflow-swc-playground Ready Ready Preview Jul 31, 2026 11:06pm
workflow-tarballs Ready Ready Preview Jul 31, 2026 11:06pm
workflow-web Ready Ready Preview Jul 31, 2026 11:06pm

@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 08567fd

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

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

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

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

Some tests failed

❌ Failed E2E Tests

▲ Vercel Production (605 failed)

astro (58 failed):

  • startFromWorkflow - calling start() directly inside a workflow function with hook communication | wrun_41KYX770XR0GQ5WS88ZJFC3K48 | 🔍 observability
  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

example (47 failed):

  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

express (49 failed):

  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

fastify (56 failed):

  • startFromWorkflow - calling start() directly inside a workflow function with hook communication | wrun_41KYX770XR0GQ5WS88ZJFC3K48 | 🔍 observability
  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

hono (55 failed):

  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

nextjs-turbopack (64 failed):

  • hookGetConflictWorkflow - hook.getConflict() resolves with the conflicting run when token is already registered | wrun_41KYX730D60GG2V76EG1XN40GE | 🔍 observability
  • hookClaimOnlyMutexWorkflow - hook works as a pure run mutex without payload data | wrun_41KYX73VPA0GYNXGFY1FEBC34Q | 🔍 observability
  • hookAdoptOwnerResultWorkflow - duplicate adopts the owner result via conflict.returnValue | wrun_41KYX73YTY0GXVKFKW9XJRXF15 | 🔍 observability
  • hookSignalOwnerWorkflow - duplicate forwards its payload to the owner via resumeHook | wrun_41KYX743XD0GJAFW5K62CB49TN | 🔍 observability
  • hookSupersedeOwnerWorkflow - duplicate cancels the owner and claims the released token | wrun_41KYX747XQ0GXYSY0GJ3SP0J3D | 🔍 observability
  • hookDisposeTestWorkflow - hook token reuse after explicit disposal while workflow still running | wrun_41KYX74QAJ0GQXKEKDWM4TDHAB | 🔍 observability
  • hookTokenReuseLoopWorkflow - same run recreates a hook with the same token after dispose() | wrun_41KYX75A1R0GSQGAWBDFB4Y69V | 🔍 observability
  • stepFunctionPassingWorkflow - step function references can be passed as arguments (without closure vars) | wrun_41KYX75PAX0GY5HG2DGJTS9HVT | 🔍 observability
  • stepFunctionWithClosureWorkflow - step function with closure variables passed as argument | wrun_41KYX760X30GVMVPYZB4643DX8 | 🔍 observability
  • closureVariableWorkflow - nested step functions with closure variables | wrun_41KYX766GC0GZ26CBBZWD8FXPG | 🔍 observability
  • spawnWorkflowFromStepWorkflow - spawning a child workflow using start() inside a step | wrun_41KYX7692V0GZC63J899ZNVAVW | 🔍 observability
  • runClassSerializationWorkflow - Run instances serialize across workflow/step boundaries | wrun_41KYX76MDW0GJD6YKPY6V8AA41 | 🔍 observability
  • startFromWorkflow - calling start() directly inside a workflow function with hook communication | wrun_41KYX770XR0GQ5WS88ZJFC3K48 | 🔍 observability
  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • pages router addTenWorkflow via pages router
  • pages router promiseAllWorkflow via pages router
  • pages router sleepingWorkflow via pages router
  • plainModuleDoneHook resumed via plain API route (o2flow shape)
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly

nextjs-webpack (58 failed):

  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • pages router addTenWorkflow via pages router
  • plainModuleDoneHook resumed via plain API route (o2flow shape)
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

nitro (56 failed):

  • startFromWorkflow - calling start() directly inside a workflow function with hook communication | wrun_41KYX770XR0GQ5WS88ZJFC3K48 | 🔍 observability
  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

nuxt (53 failed):

  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

sveltekit (55 failed):

  • startFromWorkflow - calling start() directly inside a workflow function with hook communication | wrun_41KYX770XR0GQ5WS88ZJFC3K48 | 🔍 observability
  • fibonacciWorkflow - recursive workflow composition via start() | wrun_41KYX773FY0GGBRJQHHZHKZ992 | 🔍 observability
  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

vite (54 failed):

  • pathsAliasWorkflow - TypeScript path aliases resolve correctly | wrun_41KYX76T910GKGQE11W9P1VHFT | 🔍 observability
  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81 | 🔍 observability
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK | 🔍 observability
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9 | 🔍 observability
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS | 🔍 observability
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM | 🔍 observability
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8 | 🔍 observability
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX | 🔍 observability
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX | 🔍 observability
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT | 🔍 observability
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP | 🔍 observability
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB | 🔍 observability
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5 | 🔍 observability
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F | 🔍 observability
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX | 🔍 observability
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C | 🔍 observability
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY | 🔍 observability
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A | 🔍 observability
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D | 🔍 observability
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N | 🔍 observability
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

📦 Local Production (1 failed)

nextjs-webpack-stable (1 failed):

  • webhookWorkflow | wrun_41KYX6RJXJ0GNWNZ8G3ZXBY70Y
📋 Other (108 failed)

e2e-vercel-prod-nest (54 failed):

  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortAnyInStepWorkflow: AbortSignal.any inside a step composes deserialized signals
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

e2e-vercel-prod-tanstack-start (54 failed):

  • Calculator.calculate - static workflow method using static step methods from another class | wrun_41KYX770F80GRKS6K980X5XE81
  • AllInOneService.processNumber - static workflow method using sibling static step methods | wrun_41KYX779AP0GMNV003RDY5A5HK
  • ChainableService.processWithThis - static step methods using this to reference the class | wrun_41KYX77K3N0GGG0V0K210PQ0H9
  • thisSerializationWorkflow - step function invoked with .call() and .apply() | wrun_41KYX78T5X0GM1PS2X51VHGWSS
  • customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE | wrun_41KYX77SWA0GJKP1R331Q18XQM
  • instanceMethodStepWorkflow - instance methods with "use step" directive | wrun_41KYX77X2A0GKYKHE2TFKVGWS8
  • crossContextSerdeWorkflow - classes defined in step code are deserializable in workflow context | wrun_41KYX777E80GVRPSH2Y0P1N4GX
  • errorSubclassRoundTripWorkflow - first-class Error subclasses survive every serialization boundary | wrun_41KYX786YP0GVA07K4F5R02JWX
  • stepFunctionAsStartArgWorkflow - step function reference passed as start() argument | wrun_41KYX77P4W0GQBDK0ZCHPQDCHT
  • cancelRun - cancelling a running workflow | wrun_41KYX77RZX0GTYS6KR72E83RFP
  • cancelRun via CLI - cancelling a running workflow | wrun_41KYX77M2V0GXR4K6NFTG4CPMB
  • hookWithSleepWorkflow - hook payloads delivered correctly with concurrent sleep | wrun_41KYX781SJ0GJVRAM1BGHWK1W5
  • hookWithSleepFinalStepWorkflow - step only on final payload | wrun_41KYX77NAM0GRKSNF3K9T5MB3F
  • sleepInLoopWorkflow - sleep inside loop with steps actually delays each iteration
  • sleepWithSequentialStepsWorkflow - sequential steps work with concurrent sleep (control) | wrun_41KYX78AEC0GSCKN260C92S5DX
  • AbortController abortTimeoutWorkflow: timeout cancels long-running step
  • AbortController abortParallelWorkflow: abort cancels all parallel steps
  • AbortController abortFromStepWorkflow: step abort cancels an in-flight sibling step
  • AbortController abortAlreadyAbortedWorkflow: pre-aborted signal seen by step
  • AbortController abortReasonWorkflow: abort reason preserved across boundaries
  • AbortController abortAfterCompletionWorkflow: abort after step completes is a no-op
  • AbortController abortViaHookWorkflow: external hook triggers abort on in-flight step
  • AbortController abortExternalSignalWorkflow: signal passed as workflow input
  • AbortController abortExternalSignalInFlightWorkflow: external abort fires mid-flight, propagates to nested steps
  • AbortController abortAnyInWorkflowWorkflow: AbortSignal.any composes signals inside the workflow VM
  • AbortController abortSurvivesReplayWorkflow: controller state consistent across replay
  • AbortController abortThrowIfAbortedWorkflow: throwIfAborted causes FatalError, no retries
  • AbortController abortReasonTypesWorkflow: various abort reason types propagate correctly
  • AbortController abortFetchUncaughtWorkflow: uncaught fetch AbortError is FatalError, no retries
  • AbortController abortFetchInFlightWorkflow: aborting cancels an in-flight fetch
  • AbortController abortVoidSleepTimeoutWorkflow: documented void sleep().then(abort) pattern works
  • AbortController abortDeterministicBranchWorkflow: if-check takes same path on first-run and replay
  • AbortController abortListenerWorkflow: signal.addEventListener fires on the deserialized step signal
  • AbortController abortThrowIfAbortedMidFlightWorkflow: throwIfAborted in a polling loop bails when abort fires
  • AbortController abortDeterministicBranchFromStepWorkflow: branches stay consistent when abort comes from a step
  • AbortController abortHookOrderingWorkflow [listener-first-abort-first]: addEventListener → hook.then → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [listener-first-hook-first]: addEventListener → hook.then → resumeHook → abort()
  • AbortController abortHookOrderingWorkflow [hook-first-abort-first]: hook.then → addEventListener → abort() → resumeHook
  • AbortController abortHookOrderingWorkflow [hook-first-hook-first]: hook.then → addEventListener → resumeHook → abort()
  • importMetaUrlWorkflow - import.meta.url is available in step bundles | wrun_41KYX7AE1G0GHW9BGDK5NXPF5C
  • metadataFromHelperWorkflow - getWorkflowMetadata/getStepMetadata work from module-level helper (#1577)
  • resilient start: addTenWorkflow completes when run_created returns 500 | wrun_41KYX78R7S0GG7Q5SR7CGBXFPY
  • getterStepWorkflow - getter functions with "use step" directive | wrun_41KYX79BR40GZG8YME9EQXC07H
  • distributedAbortController - manual abort triggers signal | wrun_41KYX79DKV0GPVZHDNVH5YJN4A
  • distributedAbortController - TTL expiration triggers signal | wrun_41KYX79KH00GW2EHHFWZPDEM7D
  • distributedAbortController - reconnect to existing controller | wrun_41KYX79VBF0GTFEBW4W8HMV49N
  • setAttributes start: initial attributes are seeded on run creation
  • setAttributes start: reserved-prefix initial attributes are seeded with allowReservedAttributes
  • setAttributes setAttributesWorkflow: workflow-body calls append native attr_set events and merge correctly
  • setAttributes setAttributesInsideStepWorkflow: step-body calls append attributed native events
  • setAttributes fire-and-forget: void setAttributes lands without awaiting
  • setAttributes Promise.all of disjoint-key writes: every key lands
  • setAttributes workflow throws after awaited setAttributes: attribute still persists on the failed run
  • setAttributes validation DX: invalid writes throw catchable FatalErrors naming rule and limit

E2E Test Summary

Summary
Passed Failed Skipped Total
❌ ▲ Vercel Production 850 605 239 1694
✅ 💻 Local Development 1621 0 227 1848
❌ 📦 Local Production 1620 1 227 1848
✅ 🐘 Local Postgres 1621 0 227 1848
❌ 📋 Other 912 108 212 1232
✅ vercel-multi-region 27 0 0 27
Total 6651 714 1132 8497
Details by Category

❌ ▲ Vercel Production

App Passed Failed Skipped
❌ astro 68 58 28
❌ example 79 47 28
❌ express 77 49 28
❌ fastify 70 56 28
❌ hono 71 55 28
❌ nextjs-turbopack 87 64 3
❌ nextjs-webpack 93 58 3
❌ nitro 70 56 28
❌ nuxt 73 53 28
❌ sveltekit 90 55 9
❌ vite 72 54 28

✅ 💻 Local Development

App Passed Failed Skipped
✅ astro-stable 128 0 26
✅ express-stable 128 0 26
✅ fastify-stable 128 0 26
✅ hono-stable 128 0 26
✅ nextjs-turbopack-canary 135 0 19
✅ nextjs-turbopack-stable 154 0 0
✅ nextjs-webpack-canary 135 0 19
✅ nextjs-webpack-stable 154 0 0
✅ nitro-stable 128 0 26
✅ nuxt-stable 128 0 26
✅ sveltekit-stable 147 0 7
✅ vite-stable 128 0 26

❌ 📦 Local Production

App Passed Failed Skipped
✅ astro-stable 128 0 26
✅ express-stable 128 0 26
✅ fastify-stable 128 0 26
✅ hono-stable 128 0 26
✅ nextjs-turbopack-canary 135 0 19
✅ nextjs-turbopack-stable 154 0 0
✅ nextjs-webpack-canary 135 0 19
❌ nextjs-webpack-stable 153 1 0
✅ nitro-stable 128 0 26
✅ nuxt-stable 128 0 26
✅ sveltekit-stable 147 0 7
✅ vite-stable 128 0 26

✅ 🐘 Local Postgres

App Passed Failed Skipped
✅ astro-stable 128 0 26
✅ express-stable 128 0 26
✅ fastify-stable 128 0 26
✅ hono-stable 128 0 26
✅ nextjs-turbopack-canary 135 0 19
✅ nextjs-turbopack-stable 154 0 0
✅ nextjs-webpack-canary 135 0 19
✅ nextjs-webpack-stable 154 0 0
✅ nitro-stable 128 0 26
✅ nuxt-stable 128 0 26
✅ sveltekit-stable 147 0 7
✅ vite-stable 128 0 26

❌ 📋 Other

App Passed Failed Skipped
✅ e2e-local-dev-nest-stable 128 0 26
✅ e2e-local-dev-tanstack-start- 128 0 26
✅ e2e-local-postgres-nest-stable 128 0 26
✅ e2e-local-postgres-tanstack-start- 128 0 26
✅ e2e-local-prod-nest-stable 128 0 26
✅ e2e-local-prod-tanstack-start- 128 0 26
❌ e2e-vercel-prod-nest 72 54 28
❌ e2e-vercel-prod-tanstack-start 72 54 28

✅ vercel-multi-region

App Passed Failed Skipped
✅ nextjs-turbopack 27 0 0

📋 View full workflow run

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

📊 Workflow Benchmarks

The benchmark run for 08567fd failed. See the run logs for details.

Partial results from the failed run:

commit 08567fd · Fri, 31 Jul 2026 23:21:18 GMT · run logs

Backend: vercel · app: nextjs-turbopack

Metric Scenario Best (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS step 1331 (+97%) 🔻 1437 🔴 (+43%) 🔻 1461 🔴 (+42%) 🔻 1501 🔴 (-4.9%) 30
TTFS stream 1262 (+39%) 🔻 1383 🔴 (+48%) 🔻 1394 🔴 (+47%) 🔻 1425 🔴 (+47%) 🔻 30
TTFS hook + stream 486 (+2.7%) 1626 🔴 (+25%) 🔻 1665 🔴 (+24%) 🔻 1775 🔴 (+29%) 🔻 30
STSO 1020 steps (inline) 160 (+24%) 🔻 452 (±0%) 508 (±0%) 695 (-3.1%) 1016
STSO 1020 steps (queue-hop) 2396 (+61%) 🔻 3482 (+10%) 3482 (+10%) 3482 (+10%) 3
WO 1020 steps 389282 (±0%) 389282 (±0%) 389282 (±0%) 389282 (±0%) 1
SL stream latency 90 (+20%) 🔻 135 🔴 (+17%) 🔻 137 🔴 (+7.9%) 2905 🔴 (+754%) 🔻 30
📈 STSO distribution vs main (inline / queue-hop histograms)

1020 steps (inline)

Cumulative STSO time: main 382767ms → this run 379238ms (Δ -3529ms, -1%)

  100-150 ms  ┃                         main   3  this   0    -3
  150-200 ms  █████░┃                   main  34  this  52   +18
  200-250 ms  ███████████████┃█         main 122  this 112   -10
  250-300 ms  ████████████████┃████     main 153  this 125   -28
  300-350 ms  ███████████████████░░┃    main 134  this 155   +21
  350-400 ms  █████████████████░░░░┃    main 124  this 159   +35
  400-450 ms  ████████████████████┃███  main 172  this 150   -22
  450-500 ms  ██████████████████┃██     main 153  this 138   -15
  500-550 ms  ████████░┃                main  57  this  71   +14
  550-600 ms  ██┃██                     main  37  this  22   -15
  600-650 ms  █┃                        main   7  this  14    +7
  650-700 ms  ┃                         main   7  this   8    +1
  700-750 ms  ┃                         main   5  this   4    -1
  750-800 ms  ┃                         main   1  this   2    +1
  800-850 ms  ┃                         main   2  this   2    +0
  850-900 ms  ┃                         main   0  this   2    +2
  900-950 ms  ┃                         main   1  this   0    -1
 950-1000 ms  ┃                         main   1  this   0    -1
1000-1050 ms  ┃                         main   1  this   0    -1
1100-1150 ms  ┃                         main   1  this   0    -1
1250-1300 ms  ┃                         main   1  this   0    -1

1020 steps (queue-hop)

Cumulative STSO time: main 6857ms → this run 8693ms (Δ +1836ms, +27%)

1000-1500 ms  ┃███████████████████████  main 1  this 0  -1
2000-2500 ms  ███████████████████████┃  main 1  this 1  +0
2500-3000 ms  ░░░░░░░░░░░░░░░░░░░░░░░┃  main 0  this 1  +1
3000-3500 ms  ███████████████████████┃  main 1  this 1  +0
📜 Previous results (3)

75e3abe

Fri, 31 Jul 2026 18:10:29 GMT · run logs

vercel / nextjs-turbopack

Metric Scenario Best (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS step 268 (+1.9%) 1435 🔴 (±0%) 1520 🔴 (-5.5%) 1887 🔴 (-6.0%) 30
TTFS stream 260 (+5.3%) 1466 🔴 (+4.6%) 1512 🔴 (-3.9%) 1812 🔴 (-11%) 30
TTFS hook + stream 346 (-14%) 1596 🔴 (+23%) 🔻 1656 🔴 (+22%) 🔻 1845 🔴 (+26%) 🔻 30
STSO 1020 steps (inline) 179 (+1.1%) 502 (-2.3%) 571 (-1.2%) 782 (±0%) 1016
STSO 1020 steps (queue-hop) 2133 (+44%) 🔻 2807 (+0.7%) 2807 (+0.7%) 2807 (+0.7%) 3
WO 1020 steps 438384 (+1.5%) 438384 (+1.5%) 438384 (+1.5%) 438384 (+1.5%) 1
SL stream latency 128 (+45%) 🔻 177 🔴 (+12%) 197 🔴 (+15%) 354 🔴 (+80%) 🔻 30
SO stream overhead (text) 111 (-21%) 💚 221 (+3.3%) 273 (+21%) 🔻 390 (-21%) 💚 30
SO stream overhead (structured) 119 (-11%) 211 (-22%) 💚 242 (-31%) 💚 364 (-23%) 💚 30

c784f6c

Fri, 31 Jul 2026 16:59:19 GMT · run logs

vercel / nextjs-turbopack

Metric Scenario Best (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS step 1248 (+139%) 🔻 1298 🔴 (+25%) 🔻 1316 🔴 (+23%) 🔻 1333 🔴 (-18%) 💚 30
TTFS stream 1250 (+32%) 🔻 1303 🔴 (+30%) 🔻 1317 🔴 (+28%) 🔻 1360 🔴 (+5.5%) 30
TTFS hook + stream 445 (+5.7%) 1576 🔴 (+19%) 🔻 1584 🔴 (+17%) 🔻 1629 🔴 (-8.0%) 30
STSO 1020 steps (inline) 172 (+5.5%) 465 (-1.9%) 522 (-1.7%) 676 (+0.7%) 1016
STSO 1020 steps (queue-hop) 2432 (+17%) 🔻 3265 (+2.1%) 3265 (+2.1%) 3265 (+2.1%) 3
WO 1020 steps 399054 (-1.4%) 399054 (-1.4%) 399054 (-1.4%) 399054 (-1.4%) 1
SL stream latency 90 (+9.8%) 139 🔴 (+5.3%) 175 🔴 (+19%) 🔻 196 🔴 (-8.8%) 30
SO stream overhead (text) 102 (+1.0%) 149 (-13%) 196 (-8.4%) 344 (+38%) 🔻 30
SO stream overhead (structured) 101 (-8.2%) 179 (+5.9%) 215 (+13%) 322 (+41%) 🔻 30

fedfc7a

Fri, 31 Jul 2026 01:20:43 GMT · run logs

vercel / nextjs-turbopack

Metric Scenario Best (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS step 911 (-9.4%) 1286 🔴 (+18%) 🔻 1321 🔴 (+20%) 🔻 1405 🔴 (-12%) 30
TTFS stream 1239 (+236%) 🔻 1279 🔴 (+21%) 🔻 1298 🔴 (+20%) 🔻 1366 🔴 (+23%) 🔻 30
TTFS hook + stream 1387 (+177%) 🔻 1526 🔴 (+9.0%) 1586 🔴 (+8.0%) 1628 🔴 (+8.8%) 30
STSO 1020 steps (inline) 168 (-8.7%) 466 (-5.1%) 525 (-5.9%) 780 (+3.2%) 1016
STSO 1020 steps (queue-hop) 2241 (+9.0%) 3376 (+21%) 🔻 3376 (+21%) 🔻 3376 (+21%) 🔻 3
WO 1020 steps 399756 (-7.5%) 399756 (-7.5%) 399756 (-7.5%) 399756 (-7.5%) 1
SL stream latency 79 (-8.1%) 144 🔴 (-1.4%) 155 🔴 (-16%) 💚 411 🔴 (+61%) 🔻 30
SO stream overhead (text) 105 (-23%) 💚 146 (-71%) 💚 178 (-81%) 💚 205 (-83%) 💚 30
SO stream overhead (structured) 96 (-14%) 162 (-21%) 💚 223 (-15%) 1745 🔴 (+294%) 🔻 30
ℹ️ Metric definitions & methodology

The collapsed STSO distribution section above buckets every step gap of the sequential-steps run (not a sampled window), split by whether the step ending the gap ran inline — in the same warm process as the step before it, so the gap is pure framework overhead — or after a queue-hop — the first step of a fresh process, which pays queue dispatch, client reinit and event-log replay. Bars overlay the two runs: is main, marks where this run lands, bridges the gap when this run has more samples in a bucket.

Best/P75/P90/P99 deltas compare against the most recent benchmark run on main at the time of this run. 🔻 flags a delta worse than +15%, 💚 one better than −15%.

Metrics — TTFS: time to first step body (in-deployment start() → first step body, deployment clocks) · STSO: step-to-step overhead (gap between consecutive step bodies) · WO: workflow overhead (whole-run time outside step bodies, in-deployment anchored) · SL: stream latency (in-deployment write → read propagation, readAt - writtenAt) · SO: stream overhead (end-to-end write+consume time beyond the modelled generation window)

Scenarios — step: one trivial no-op step, no stream; no hooks, so the run stays in turbo mode (in-process fast path) · stream: one streaming step; no hooks, so the run stays in turbo mode (in-process fast path) · hook + stream: registers a hook before one step, which exits turbo mode (dispatch path) · 1020 steps: 1020 trivial sequential steps; STSO is measured between consecutive steps in the given step ranges, and WO is the whole-run overhead outside step bodies · stream latency: parallel reader/writer steps on a dedicated stream; SL is the in-deployment write->read propagation (readAt - writtenAt) · stream overhead (text): writer streams 300 variable-length text token deltas paced at 100/s for 3s (a haiku-size LLM's token throughput) while a parallel reader drains the whole stream; SO is the end-to-end write+consume time beyond the 3s generation window (overhead/backpressure) · stream overhead (structured): same workload as stream overhead (text), but each delta is an AI-SDK-style structured object ({ type: 'text-delta', id, text }) instead of a raw string, so the SO gap vs the text scenario is the added serialization cost

🔴 marks a percentile over its target (within target is left unmarked). Targets (p75/p90/p99, ms) — TTFS 200/300/600 · SL 50/60/125

All metrics are measured from deployment-side timestamps only. Runs are triggered by an in-deployment route that stamps the anchor (clientStart) right before start(), so the CI runner’s request and its path through api.vercel.com sit outside every measured window. TTFS = in-deployment start() → first step body (turbo uses the in-process fast path, non-turbo the dispatch path), and includes the VQS dispatch hop plus any /flow cold start. STSO/WO are measured between step bodies on the deployment. SL is measured inside the workflow (parallel reader/writer steps), so it no longer includes the api.vercel.com read path.

Cold starts are kept in the numbers on purpose — they are part of real bursty-workload latency. The workbench deployment cold-starts the /flow invocation for a large fraction of runs, inflating P75+; the Best column shows the fastest (warm-start) sample for comparison.

@shalabhc
shalabhc marked this pull request as ready for review July 31, 2026 01:34
@shalabhc
shalabhc requested review from a team and ijjk as code owners July 31, 2026 01:34

@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.

Reviewed the capture, the threading, and the renderer. Approving — this closes a real gap in the histogram section (I've done the deployment-id + time-window hunt this replaces), and the degradation matrix is genuinely complete: every optional field falls back the way the table claims, and the three new renderer tests cover the full/degraded/omitted cases (40/40 pass locally).

One correction worth making before merge — the route comment overclaims what the trace contains. route.ts says the trigger request's span "propagates into the workflow's own spans". That's only true under WORKFLOW_TRACE_MODE=continuous. Nothing in the workbench or benchmarks.yml sets the mode, so the benchmark deployment runs the default linked mode — where each workflow/step invocation is its own trace root, and the trigger request's trace contains only the workflow.start span plus span links to the execution roots. The link is still useful (one hop via span links, and Datadog renders those), but:

  • the comment should say what's actually there, so nobody debugging a weird histogram concludes the run "has no spans" when they open a trigger-only trace; and
  • consider making the link a Datadog APM search on workflow.run.id:<runId> instead of (or alongside) the trace permalink — under linked mode that lands on the run's actual execution spans directly, which is where an STSO investigation actually goes. The run id is already in hand.

Fine to take the comment fix now and the search-link idea as a follow-up — the current link is strictly better than nothing either way.

Verified:

  • The capture is correctly optional end-to-end: optional-chained getActiveSpan() (undefined without OTEL → bare run id), type-guarded on the runner side (typeof data.traceId === 'string'), and sequentialRuns omitted rather than [] when the scenario didn't run — so old artifacts, old deployments, and history re-renders all degrade exactly per the table.
  • Recording all iterations' run refs matches the data: the histograms aggregate samples across iterations, so with BENCH_SEQUENTIAL_ITERATIONS > 1 the comma-joined list is the honest answer. The doc phrase "both histograms come out of the same iteration" is only true for the default single-iteration config — worth a "(iterations, when configured)" tweak since the code already handles N correctly.
  • Baseline matching reuses the same methodology/backend/app key the percentile baselines use (resultKeyFor = the metric key minus the row), so the two sides of the diff can't come from mismatched configurations.
  • The empty changeset is correct — e2e runner, CI scripts, and a workbench route; nothing published changes.

One robustness nit, non-blocking: runId/traceId are spliced into the markdown link unvalidated. The artifact-trust model is consistent with the rest of this renderer, so it's not a security gap — but a cheap shape check (/^[a-z0-9_]+$/i) before rendering the link would keep a malformed value from a buggy deployment from breaking the whole comment's markdown, which is this section's own failure story.

CI: the 2 failures are the nextjs-webpack canary HMR rebuild-count test and its required-check aggregator — the long-running baseline flake, unreachable from a benchmark-comment change.

The route comment claimed the trigger request's span "propagates into
the workflow's own spans". That only holds under
WORKFLOW_TRACE_MODE=continuous. Nothing in the workbench or
benchmarks.yml sets the mode, so the benchmark deployment runs the
default `linked` (packages/core/src/telemetry.ts), where each
workflow/step invocation is its own trace root and the trigger's trace
carries `workflow.start` plus span links out to those roots.

The logged link is still the right entry point -- one hop through the
links, which Datadog renders -- but the comment should describe that,
so nobody opening a trigger-only trace while debugging a histogram
concludes the run produced no spans.

Raised by @TooTallNate in review of #3248.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Co-Authored-By: Shalabh Chaturvedi <7066873+shalabhc@users.noreply.github.com>
Under the default linked trace mode the trigger's trace holds only
`workflow.start` plus span links, so opening it lands one hop away from
the spans an STSO investigation needs. Log an APM search on
`@workflow.run.id:<runId>` next to it, which goes straight to the run's
execution spans.

Both links are logged rather than one replacing the other: the search
depends on `workflow.run.id` being an indexed span tag in the org, and
the permalink works regardless.

Suggested by @TooTallNate in review of #3248.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Co-Authored-By: Shalabh Chaturvedi <7066873+shalabhc@users.noreply.github.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.

2 participants