* fix(build): use inline sourcemaps across all workspace packages
Prevents a Turbopack bug on Windows that caused the SWC worker to
crash when reading external .js.map files in workspace-linked packages
(paths were concatenated with mixed separators like
'packages/serde/dist\\index.js.map'). Once the worker crashed, the
module graph entered a broken state where all subsequent requests
returned 500, manifesting as flaky E2E Windows tests where the
'should rebuild on imported step dependency change' test would time
out waiting for /api/workflows/start to succeed.
Extends the original fix from #352 (previously applied only to
@workflow/core and workflow) to the shared base tsconfig.json so that
all packages producing a dist/ output benefit.
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Nathan Rajlich <n@n8.io>
* Tighten changeset description
---------
Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* docs: split v4/v5 content, fix version switcher end-to-end
## Content restructuring
- Split `docs/content/docs/` into `docs/content/docs/v4/` and
`docs/content/docs/v5/` so each version is a fully independent
content tree with no shared-file coupling
- v4 excludes the four pages that are v5-only (AbortController
cancellation docs and the serializable-abort-controller internal page)
- v5 retains all pages; `preRelease` frontmatter field removed (no
longer needed now that each version is its own folder)
- Removed `AbortController` / `AbortSignal` from v4 serialization page
(section moved to v5 only)
## Fumadocs source
- Added `v4docs` and `v5docs` as separate `defineDocs()` collections in
`source.config.ts`; shared `docsSchema` (no more `preRelease` field)
- `source.ts` exports both `source` (v4, `baseUrl: /docs`) and
`v5Source` (v5, same base URL)
## Version routing
- `version-source.ts` simplified: `filterPreReleaseFromNodes` and
`isPreReleaseUrl` logic removed; v4 tree uses `source`, v5 tree uses
`v5Source` + `rewriteNodeUrls`
- v4 `page.tsx`: removed `preRelease` guard (v4Source has no such pages)
- v5 `page.tsx`: uses `v5Source` for `getPage` / `generateStaticParams`
/ `generateMetadata`; `v5Link` wrapper rewrites `/docs/…` hrefs to
`/v5/docs/…` so inline MDX links stay in the v5 context
## Versioned cookbook
- Added `app/[lang]/v5/cookbook/` layout + page (mirrors v4 but uses
`v5Source`, `rewriteCookbookUrlForVersion`, and `V5CookbookLink`)
- `getCookbookTree` accepts a `versionPrefix` parameter; sidebar URLs
are prefixed accordingly (`/v5/cookbook/…`)
- `cookbook-tree.ts`: added `skipVersions?: string[]` per-recipe field
for version-specific exclusions; `distributed-abort-controller` is
marked `skipVersions: ['v5']`
## Version switcher — state & navigation
- New `VersionProvider` context (`hooks/geistdocs/use-version.tsx`)
backed by `localStorage`: URL is source of truth on versioned pages,
`localStorage` carries the preference across non-versioned pages
(cookbook overview, worlds, etc.)
- `VersionSwitcher` uses `useVersion()` context instead of URL-only
detection; now visible on all pages including cookbook
- `DesktopMenu` and `MobileMenu` use `activeVersion` from context so
the "Docs" and "Cookbook" navbar links resolve to the correct version
prefix on every page
- `buildVersionUrl` expanded to handle `/cookbook/…` paths alongside
`/docs/…`; non-versioned routes (worlds, api) return unchanged
- `switchVersion` does a `HEAD` probe before navigating; falls back to
the versioned cookbook or docs home if the target page doesn't exist
in that version (handles v4-only → v5 and v5-only → v4 cases)
## Cookbook content (v5)
- Rewrote `agent-cancellation` recipe using a single `AbortController`
pattern; removed Hard Cancellation vs Stop Signal two-approach
comparison
- Deleted `distributed-abort-controller` recipe from v5 (native
`AbortController` serialization makes it unnecessary)
- Removed references to distributed-abort-controller from
`cookbook/index.mdx` and `common-patterns/timeouts.mdx`
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(docs): use abortSignal (not signal) in DurableAgent.stream() options
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(docs): update prepack scripts to use versioned content paths
Content moved from docs/content/docs/ to docs/content/docs/v5/ on main
(pre-release channel). Stable branch will use v4/ after backport.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* Add stable Next.js eager and lazy test coverage
* Address PR review feedback
* Fix eager Next step route builds
* Fix eager Next manifest refreshes
* Fix eager Next e2e stack assertions
* Externalize native step bundle bindings
* Lazy load Vercel world runtime
* Fix Next dev step sourcemap assertions
* Consolidate eager build changesets
* Fix Vercel world tracing in Next deployments
* Externalize Vercel world in Next builds
* Fix webpack tracing for Vercel world deps
* Fix eager workflow route bundling
* Rely on Next server externals
* feat: allow start() to be called directly inside workflow functions
Add 'use step' to start() so it can be called directly from workflow
code. The SWC compiler strips the function body in workflow mode and
replaces it with a step proxy. When called from a workflow:
1. The workflow function reference is serialized via WorkflowFunction
reducer (serializes { workflowId })
2. start() executes in the step context with full Node.js access
3. The returned Run is serialized via WORKFLOW_SERIALIZE and deserialized
back in the workflow VM
4. Run getters (.status, .returnValue, etc.) are 'use step' getters
that each execute as separate steps
Also re-exports start from @workflow/core/runtime/start in api-workflow.ts
instead of using a throwing stub, adds e2e tests for startFromWorkflow
(with hook communication) and fibonacciWorkflow (recursive composition).
* fix(next): don't copy package step files in deferred builder to avoid duplicate classes
Files belonging to packages (detected by walking up to find a
package.json with a name field) are imported via relative path
instead of being copied to __workflow_step_files__/. Copying creates
a second module instance which breaks JS native private field (#)
brand checks when the runtime creates instances from one copy and
the step handler accesses fields from the other.
* fix(next): only skip copying package files that are serde classes, not all package step files
Regular package step files (like fetch) must still be copied to ensure
the SWC loader registers them. Only serde class files from packages are
excluded from copying since those define classes with JS native private
fields (#) that break when duplicated.
* fix(next): generate thin wrappers for package serde step files instead of full copies
For package files that define serde classes (like Run), generate a thin
wrapper that imports the original class and registers steps/classes from
the manifest. This avoids duplicating the class definition (which breaks
JS native private field brand checks) while still registering all step
functions and the class in the serialization registry.
Regular package step files (like fetch) are still copied as before.
* fix(next): use forceStepModeFiles to transform package serde files in step mode
Instead of copying package serde+step files (which creates duplicate
classes with #private brand check issues) or generating fragile wrappers,
add the original file paths to a shared forceStepModeFiles set. The
loader checks this set and transforms those files in step mode directly,
so the SWC plugin generates proper step registrations on the original
class — no duplication, no reimplemented registration logic.
* fix(next): use step mode for all files with step/serde patterns, not just copies
The loader now selects step mode for any file that has 'use step'
directives or serde patterns, regardless of whether it's a deferred
step copy. Step mode is a superset of client mode — the only addition
is step registry IIFEs, which are harmless for non-step consumers.
This means package serde+step files (like Run) no longer need to be
copied to get step registrations. They're imported directly in the
step route and the loader transforms the original file in step mode.
One class instance, no duplication, no wrapper generation.
---------
Co-authored-by: Nathan Rajlich <n@n8.io>
* [docs] Rename workflowdevkit references to workflowsdk
* [docs] Rename useworkflow.dev to workflow-sdk.dev
* [chore] Add changeset for domain rename
* [docs] Revert sitemap rewrite to useworkflow.dev (crawled-sitemap not yet available for new domain)
* feat: serialize Run via custom class serialization with "use step"
Single Run class implementation:
- Add WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE to core Run class
- Mark all runtime-dependent methods/getters with "use step" so SWC
strips their bodies from the workflow bundle
- Remove duplicate Run stub from api-workflow.ts; re-export core Run
- SWC auto-registers the class (no manual registerSerializationClass)
- Add e2e test for Run serialization across workflow/step boundaries
- Add unit tests for serde roundtrip
* chore: bump changeset to minor (new feature)
* fix: include resilientStart in Run serde payload and add readable getter comment
* .
* fix: remove eager getWorld() from constructor, rely on lazy getter
The SWC compiler plugin no longer generates import statements. All step
function registrations and closure variable access are now self-contained
inline IIFEs with zero module dependencies
Use named export instead of `export =` in the CJS shim so that
Node.js cjs-module-lexer can detect withWorkflow as a named export,
enabling `import { withWorkflow } from 'workflow/next'` in ESM.
The previous pre-release versions (4.x.y-beta.N) caused two issues:
- semver.inc('4.0.0-beta.N', 'major') returns 4.0.0, not 5.0.0
- Pre-release numbers carried over (beta.61 -> beta.62 instead of beta.0)
Setting all versions to 4.0.0 (non-pre-release) ensures a clean major
bump to 5.0.0-beta.0. Also removes @workflow/swc-playground-wasm from
the changeset and pre.json since it is a private package.
* Rename 'Workflow Development Kit' / 'DevKit' to 'Workflow SDK' across docs, code, and config
Follow-up to cdf90d5a38 (#1541)
* Fix missing </h1> closing tag and add article 'the' before 'Workflow SDK' in docs
* feat: enhance error handling for missing workflow functions
Slack-Thread: https://vercel.slack.com/archives/C09G3EQAL84/p1773856370214769?thread_ts=1773856370.214769&cid=C09G3EQAL84
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>
* fix: update step not found handling to match FatalError pattern
Move step function validation after step_started and call step_failed directly if not found.
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>
* changes
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
* feat: add StepNotRegisteredError and WorkflowNotRegisteredError semantic errors
Introduce dedicated error types for when step/workflow functions are not
registered in the current deployment, replacing generic WorkflowRuntimeError.
These are infrastructure errors (not user code errors) with proper error
slugs, docs pages, and a new FUNCTION_NOT_REGISTERED error code.
Step not found fails the step (like FatalError) so the workflow can handle
it gracefully. Workflow not found fails the run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review comments
- Remove FUNCTION_NOT_REGISTERED error code, use RUNTIME_ERROR instead
- Use .is() instead of instanceof for WorkflowRuntimeError check in runtime.ts
- Remove non-working example from WorkflowNotRegisteredError docs (custom
errors not serialized yet)
- Update all references from FUNCTION_NOT_REGISTERED to RUNTIME_ERROR
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add e2e tests for step/workflow not registered errors and fix docs typecheck
E2E tests:
- WorkflowNotRegisteredError: start a run with a fake workflowId, verify
the run fails with RUNTIME_ERROR
- StepNotRegisteredError (caught): workflow catches the step failure,
verify workflow completes and step is marked failed
- StepNotRegisteredError (uncaught): verify the run fails when workflow
doesn't catch the error
Step not registered is tested by manually invoking useStep with a
non-existent step ID in the workflow VM — this is the same pattern the
SWC transform generates for real step calls.
Also fix docs typecheck by using declare/\@setup pattern instead of
\@skip-typecheck for code samples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: cast globalThis to any for Symbol index access in e2e workflow
TypeScript's strict mode doesn't allow using a symbol to index
globalThis. Cast to any since this runs in the workflow VM where
the symbol is defined.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: classify WorkflowNotRegisteredError as RUNTIME_ERROR
The .is() check uses name-based matching, so WorkflowNotRegisteredError
(name='WorkflowNotRegisteredError') doesn't match WorkflowRuntimeError.is().
Add explicit check in classifyRunError so the error code is RUNTIME_ERROR
instead of USER_ERROR.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use instanceof for WorkflowRuntimeError checks, improve docs
Address PR review feedback:
1. Revert .is() checks back to instanceof WorkflowRuntimeError in
runtime.ts and classify-error.ts. instanceof catches all subclasses
(current and future), which is the correct behavior for these catch
blocks.
2. Remove duplicated try/catch example from step-not-registered-error
API reference (troubleshooting page already has it).
3. Add Callout in API reference docs clarifying that .is() works in
server-side Node.js code but not inside "use workflow" functions
where errors arrive deserialized from the event log.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* changes
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
---------
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: v0 <v0[bot]@users.noreply.github.com>
Co-authored-by: Pranay Prakash <1797812+pranaygp@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: export semantic error types and add API reference documentation
Add missing error exports (HookNotFoundError, EntityConflictError,
RunExpiredError, TooEarlyError, ThrottleError, RunNotSupportedError,
WorkflowWorldError) to workflow/internal/errors. Create new error
classes for world-level semantics. Tighten TSDoc comments on all
error classes. Add API reference docs for all error types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use @setup declarations, workflow/errors import, and errors/ doc section
- Replace @skip-typecheck with proper `declare` + `// @setup` lines
so code samples are typechecked but setup lines hidden from readers
- Add `workflow/errors` export to package.json (public API, replaces
`workflow/internal/errors` in docs)
- Add `workflow/errors` path mapping in docs-typecheck type-checker
- Add HookConflictError to re-export list
- Move all error docs under api-reference/workflow/errors/ subdirectory
- Update all internal cross-references and links
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move error docs to top-level workflow-errors section
- Move semantic error docs to api-reference/workflow-errors/ (matching
the workflow/errors import path, like workflow-api for workflow/api)
- Keep FatalError and RetryableError in api-reference/workflow/ since
they're imported from workflow, not workflow/errors
- Fix all cross-reference links
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update HTTP debug logger JSDoc to clarify scope
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make TooEarlyError.retryAfter a number (seconds) matching WorkflowWorldError
TooEarlyError.retryAfter is now seconds (number) instead of a Date,
consistent with ThrottleError and WorkflowWorldError. The conversion
from seconds to Date is done at the consumer site (step-handler) rather
than at construction time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address review feedback on docs accuracy
- WorkflowWorldError docs: add status, code, url, retryAfter properties
to TSDoc; clarify that .is() only matches direct instances (not
subclasses); use instanceof in catch-all example
- TooEarlyError/ThrottleError docs: mark retryAfter as optional (?)
to match actual type definitions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add support for calling `start()` directly inside workflow functions
Enable `start()` to work in workflow context by routing through an
internal step (`__workflow_start`), reusing existing step infrastructure
with no new event types or server changes needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review feedback
- Use typeof check instead of truthiness for WORKFLOW_START symbol
- Validate start() options in workflow context (reject unsupported options like world)
- Set maxRetries=0 on __workflow_start step to prevent orphaned child runs
- Add unit tests for createStart factory (6 tests)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Make Run serializable in workflow context with step-backed methods
- Add Run serialization via __serializable marker + custom Run reducer/reviver
in the serialization module (avoids SWC plugin injecting class-serialization imports)
- Create WorkflowRun class factory (packages/core/src/workflow/run.ts) with
step-backed methods: cancel(), status, returnValue, workflowName, createdAt,
startedAt, completedAt, exists
- Register 8 built-in steps (__run_cancel, __run_status, etc.) in step-handler
- Update __workflow_start to return full Run object (serialized → WorkflowRun in VM)
- Update createStart to pass through step result directly
- Update docs to reflect full Run support in workflow context
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix start() in workflow VM by delegating from api-workflow stub
The workflow VM loads api-workflow.ts (via the "workflow" export condition)
which stubs all runtime functions. The start stub needs to check for the
injected WORKFLOW_START symbol and delegate to it, otherwise start() throws
"doesn't allow this runtime usage" in the workflow context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address PR review: fix stale WORKFLOW_SERIALIZE comments and register Run in host registry
- Update comments in step-handler.ts and start.ts to reference the actual
serialization mechanism (Run reducer with __serializable marker) instead
of the stale WORKFLOW_SERIALIZE reference
- Register Run class in the host's class registry from step-handler.ts so
the Run reviver can deserialize Run/WorkflowRun instances in step context
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add docs for recursive/repeating workflows and deploymentId: "latest"
- Document using start() for self-chaining workflows to avoid large event logs
- Add examples for batch processing and cron-like repeating patterns
- Document deploymentId: "latest" option with type safety warning
- Update skill file with same patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Return full Run object from startFromWorkflow e2e workflow
Update the e2e workflow to return the childRun object directly instead of
just childRun.runId, exercising Run serialization across the workflow boundary.
Update e2e test assertions to match.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add recursive fibonacci e2e test for start() in workflow
Demonstrates recursive workflow composition: fibonacciWorkflow starts
new instances of itself via start() + Promise.all to compute fib(6)=8,
fanning out across independent workflow runs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Move Run method steps to builtins with "use step" directives
Refactor: instead of manually registering Run method steps via
registerStepFunction in step-handler.ts, define them as proper "use step"
functions in builtins.ts with __builtin_ prefix. This leverages the
existing SWC plugin infrastructure — functions starting with "__builtin"
get stable bare-name step IDs.
- Add __builtin_run_{cancel,status,return_value,...} to both builtins files
- Use dynamic import() for getRun inside step bodies to avoid pulling
Node.js modules into the workflow bundle
- Remove manual registerStepFunction calls from step-handler.ts
- Update WorkflowRun step references to __builtin_run_* names
- Fix step name display in web observability: fall back to raw name
instead of "?" for built-in steps that don't follow step//module//fn format
- Add fibonacciWorkflow default args for nextjs-turbopack workbench UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Render Run objects as clickable links in web observability UI
- Add RunRef type and Run reviver to observabilityRevivers so serialized
Run objects are hydrated as RunRef instead of showing raw Uint8Array
- Add RunRefInline component (purple badge with run ID) that navigates
to the target run on click, matching the StreamRef pattern
- Thread onRunClick callback through the component chain:
WorkflowTraceViewer → EntityDetailPanel → AttributePanel → DataInspector
- Wire up navigation in the web app's run-detail-view
- Add startFromWorkflow default args for workbench UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Throw error instead of silent fallback when Run class not in registry
Address PR review: the Run reviver now throws if the class isn't found
in the registry, instead of silently returning a plain { runId } object
that would break the assumption of getting a valid Run instance.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix e2e failures: allow retries on Run getter steps, fix docs code samples
- Remove maxRetries=0 from read-only Run getter steps (status, returnValue,
workflowName, etc.) — these are safe to retry and need retries when the
child workflow hasn't completed within the step timeout. Only cancel
keeps maxRetries=0.
- Fix docs code samples: use correct import path (workflow/api not workflow),
add declare statements for helper functions used in examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use standard step//module//function naming for built-in steps
Update the SWC plugin's __builtin_ special case to generate proper
step//@workflow/core//{name} IDs instead of bare function names. This
makes parseStepName work correctly for built-in steps, showing:
- StepName: "Run#returnValue" (not "__builtin_run_return_value")
- ModuleSpecifier: "@workflow/core" (not the raw function name)
Convention: __builtin_Run_cancel → step//@workflow/core//Run#cancel
(uppercase prefix + underscore → instance method # notation)
- Move __workflow_start to builtins.ts as __builtin_start
- Rename __builtin_run_* to __builtin_Run_* for proper # notation
- Update WorkflowRun step refs to use full step// IDs
- Remove manual registerStepFunction from step-handler.ts
- Update SWC spec.md with new naming examples
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove SWC __builtin special case, use standard step naming for builtins
Remove the SWC plugin's __builtin_ special case so built-in steps get
standard step//{module}@{version}//{fn} IDs like any other step. This
makes parseStepName work correctly, showing proper StepName and
ModuleSpecifier in observability.
The VM reconstructs the same IDs via builtinStepId() which uses the
@workflow/core version to build: step//workflow/internal/builtins@{v}//{fn}
- Remove __builtin special case from SWC plugin (revert to original)
- Add builtinStepId() helper shared by workflow.ts, start.ts, run.ts
- Rename Run steps: __builtin_Run_cancel → Run_cancel, etc.
- Rename start step: __builtin_start → start
- Move start step from manual registerStepFunction to builtins.ts
- Keep __builtin_response_* names unchanged (pre-existing)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use static class methods for Run steps to get Run.method naming
Refactor Run method steps from standalone functions (Run_cancel) to
static methods on a Run class, so the SWC plugin generates step IDs
with the standard static method convention: Run.cancel, Run.returnValue,
Run.status, etc.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address PR review: tests, docs warnings, skill fix
- Add TODO on Run.returnValue about polling blocking (replace with system
hooks once AbortSignal/AbortController PR lands)
- Add docs callout warning about returnValue holding workers alive
- Fix SKILL.md contradiction that said start() can't be used in workflows
- Enhance suspension test to assert step arguments are forwarded
- Add WorkflowRun unit tests: serializable marker, runId, registry, delegation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix response builtins: adopt this-serialization from PR #1413
The rebase onto main didn't fully adopt PR #1413's refactor of response
builtins to use `this` instead of explicit parameters. The old pattern
(resJson(this) wrappers) passed `this` as an argument, but the step
functions now expect `this` to be set via method call context.
Switch to Object.defineProperties on Request/Response prototypes,
matching main's approach. Also document WORKFLOW_PUBLIC_MANIFEST=1
for local e2e testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address docs review: returnValue polling is temporary, link to start() API ref
- Update returnValue warning to note this is a temporary implementation
that will be replaced with internal hooks
- Replace inline deploymentId: "latest" docs with link to the existing
start() API reference which already covers it comprehensively
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix e2e tests: replace collectedRunIds with trackRun API
PR #1426 replaced the manual collectedRunIds array with a trackRun()
helper. The start() wrapper already auto-tracks, so just remove the
manual push calls and add trackRun for the child run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: classify run failure error codes and improve error logging
- Add RUN_ERROR_CODES (USER_ERROR, RUNTIME_ERROR) to @workflow/errors
- Populate errorCode in run_failed events via classifyRunError()
- Update web UI StatusBadge to show amber dot for infrastructure errors
- Improve world-local queue error logging (concise, no body dump)
- Improve schema validation error messages (concise, verbose behind DEBUG)
- Add e2e tests for error code flow and infrastructure error retry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add semantic error types to replace HTTP status code checks in runtime
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: classify run failure error codes and improve error logging
- Add RUN_ERROR_CODES (USER_ERROR, RUNTIME_ERROR) to @workflow/errors
- Populate errorCode in run_failed events via classifyRunError()
- Update web UI StatusBadge to show amber dot for infrastructure errors
- Improve world-local queue error logging (concise, no body dump)
- Improve schema validation error messages (concise, verbose behind DEBUG)
- Add e2e tests for error code flow and infrastructure error retry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: classify run failure error codes and improve error logging
- Add RUN_ERROR_CODES (USER_ERROR, RUNTIME_ERROR) to @workflow/errors
- Populate errorCode in run_failed events via classifyRunError()
- Update web UI StatusBadge to show amber dot for infrastructure errors
- Improve world-local queue error logging (concise, no body dump)
- Improve schema validation error messages (concise, verbose behind DEBUG)
- Add e2e tests for error code flow and infrastructure error retry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* address PR review comments
- Remove dead `meta` option from TooEarlyError constructor (TooTallNate)
- Extract `throwWithTrace` helper to deduplicate span recording in
world-vercel makeRequest (TooTallNate)
- Restore `maxAttempts` const for stable retry count logging (TooTallNate)
- Fix behavioral regression: add WorkflowAPIError 404 fallback in
suspension-handler hook disposal to handle world-vercel path where
makeRequest doesn't map 404 to HookNotFoundError (TooTallNate)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: translate 404 to HookNotFoundError at the world-vercel boundary
Move the 404 → HookNotFoundError translation into world-vercel's
createWorkflowRunEvent, where we know the event type context. For
hook-related events (hook_created, hook_disposed, hook_received,
hook_conflict), a 404 from the server means the hook was not found.
This removes the WorkflowAPIError 404 fallback from the runtime's
suspension-handler, keeping the runtime fully decoupled from HTTP
status codes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: parse Retry-After for 425 responses and narrow hook event set
- Parse Retry-After header unconditionally so TooEarlyError gets
the server-provided delay instead of always falling back to ~1s
- Narrow hookEventsRequiringExistence to only hook_disposed and
hook_received (matching world-local's set), since hook_created
and hook_conflict don't imply the hook must already exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* rename WorkflowAPIError to WorkflowWorldError
Breaking change: rename WorkflowAPIError → WorkflowWorldError to
better reflect that this error represents world (storage backend)
failures, not HTTP API errors specifically. Updated across all
packages: errors, core, world-local, world-vercel, world-postgres,
workflow, and web.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: use `this` value serialization for builtin step functions
Refactor builtin step functions (__builtin_response_json, _text,
_array_buffer) to use `this` instead of an explicit parameter,
leveraging the useStep() proxy's this value serialization support.
- Assign useStep() proxies directly onto Request.prototype and
Response.prototype instead of wrapping them in class methods
- Update builtin function signatures to use `this: Request | Response`
- Remove unused duplicate builtins file from @workflow/core
(the canonical copy lives in workflow/src/internal/builtins.ts)
* use Object.defineProperties for non-enumerable prototype methods