workflow 4.2.0-beta.71 → 4.2.0-beta.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/api.d.ts +1 -1
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js +1 -1
  4. package/dist/internal/errors.d.ts +1 -1
  5. package/dist/internal/errors.d.ts.map +1 -1
  6. package/dist/internal/errors.js +2 -2
  7. package/dist/observability.d.ts +20 -0
  8. package/dist/observability.d.ts.map +1 -0
  9. package/dist/observability.js +20 -0
  10. package/docs/ai/defining-tools.mdx +6 -0
  11. package/docs/ai/index.mdx +3 -0
  12. package/docs/ai/message-queueing.mdx +2 -0
  13. package/docs/ai/resumable-streams.mdx +37 -4
  14. package/docs/ai/sleep-and-delays.mdx +2 -0
  15. package/docs/api-reference/meta.json +1 -1
  16. package/docs/api-reference/workflow/define-hook.mdx +2 -0
  17. package/docs/api-reference/workflow/get-writable.mdx +1 -0
  18. package/docs/api-reference/workflow-ai/durable-agent.mdx +2 -0
  19. package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +2 -0
  20. package/docs/api-reference/workflow-api/get-run.mdx +14 -0
  21. package/docs/api-reference/workflow-api/get-world.mdx +105 -0
  22. package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +60 -0
  23. package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +90 -0
  24. package/docs/api-reference/workflow-errors/meta.json +16 -0
  25. package/docs/api-reference/workflow-errors/run-expired-error.mdx +58 -0
  26. package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +56 -0
  27. package/docs/api-reference/workflow-errors/throttle-error.mdx +62 -0
  28. package/docs/api-reference/workflow-errors/too-early-error.mdx +62 -0
  29. package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +57 -0
  30. package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +56 -0
  31. package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +62 -0
  32. package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +56 -0
  33. package/docs/api-reference/workflow-errors/workflow-world-error.mdx +79 -0
  34. package/docs/changelog/index.mdx +15 -0
  35. package/docs/changelog/meta.json +5 -0
  36. package/docs/deploying/building-a-world.mdx +20 -0
  37. package/docs/errors/hook-conflict.mdx +9 -3
  38. package/docs/errors/index.mdx +6 -0
  39. package/docs/errors/step-not-registered.mdx +66 -0
  40. package/docs/errors/webhook-invalid-respond-with-value.mdx +10 -0
  41. package/docs/errors/webhook-response-not-sent.mdx +8 -0
  42. package/docs/errors/workflow-not-registered.mdx +64 -0
  43. package/docs/foundations/errors-and-retries.mdx +29 -0
  44. package/docs/foundations/streaming.mdx +22 -0
  45. package/docs/getting-started/index.mdx +3 -3
  46. package/docs/getting-started/meta.json +15 -0
  47. package/docs/getting-started/nestjs.mdx +4 -8
  48. package/package.json +18 -12
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: StepNotRegisteredError
3
+ description: Thrown when a step function is not registered in the current deployment.
4
+ type: reference
5
+ summary: Catch StepNotRegisteredError when a step function cannot be found during execution.
6
+ related:
7
+ - /docs/errors/step-not-registered
8
+ - /docs/api-reference/workflow-errors/workflow-not-registered-error
9
+ ---
10
+
11
+ `StepNotRegisteredError` is thrown when the runtime tries to execute a step function that is not registered in the current deployment. This is an infrastructure error — not a user code error. It typically indicates a build or bundling issue that caused the step to not be included in the deployment.
12
+
13
+ When this error occurs, the step fails (like a `FatalError`) and control is passed back to the workflow function, which can handle the failure gracefully.
14
+
15
+ ```typescript lineNumbers
16
+ import { StepNotRegisteredError } from "workflow/errors"
17
+ declare const error: unknown; // @setup
18
+
19
+ if (StepNotRegisteredError.is(error)) { // [!code highlight]
20
+ console.error("Step not registered:", error.stepName);
21
+ }
22
+ ```
23
+
24
+ ## API Signature
25
+
26
+ ### Properties
27
+
28
+ <TSDoc
29
+ definition={`
30
+ interface StepNotRegisteredError {
31
+ /** The name of the step function that was not found. */
32
+ stepName: string;
33
+ /** The error message. */
34
+ message: string;
35
+ }
36
+ export default StepNotRegisteredError;`}
37
+ />
38
+
39
+ ### Static Methods
40
+
41
+ #### `StepNotRegisteredError.is(value)`
42
+
43
+ Type-safe check for `StepNotRegisteredError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
44
+
45
+ <Callout>
46
+ The `.is()` method works in server-side Node.js code (API routes, middleware, hooks). Inside `"use workflow"` functions, step errors arrive deserialized from the event log and won't be actual `StepNotRegisteredError` instances — use `error.message` matching instead. See the [troubleshooting page](/docs/errors/step-not-registered) for workflow-side error handling examples.
47
+ </Callout>
48
+
49
+ ```typescript
50
+ import { StepNotRegisteredError } from "workflow/errors"
51
+ declare const error: unknown; // @setup
52
+
53
+ if (StepNotRegisteredError.is(error)) {
54
+ // error is typed as StepNotRegisteredError
55
+ }
56
+ ```
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: ThrottleError
3
+ description: Thrown when a request is rate-limited by the workflow backend.
4
+ type: reference
5
+ summary: Catch ThrottleError when a workflow storage operation is rate-limited (HTTP 429).
6
+ related:
7
+ - /docs/api-reference/workflow-errors/workflow-world-error
8
+ - /docs/api-reference/workflow-errors/too-early-error
9
+ ---
10
+
11
+ `ThrottleError` is thrown when a request to the workflow backend is rate-limited. It corresponds to HTTP 429 Too Many Requests semantics.
12
+
13
+ The `retryAfter` property contains the number of seconds to wait before retrying.
14
+
15
+ <Callout>
16
+ The Workflow runtime handles this error automatically by backing off and retrying. You will only encounter it when interacting with world storage APIs directly.
17
+ </Callout>
18
+
19
+ ```typescript lineNumbers
20
+ import { ThrottleError } from "workflow/errors"
21
+ declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
22
+ declare const runId: string; // @setup
23
+ declare const event: any; // @setup
24
+
25
+ try {
26
+ await world.events.create(runId, event);
27
+ } catch (error) {
28
+ if (ThrottleError.is(error)) { // [!code highlight]
29
+ console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
30
+ }
31
+ }
32
+ ```
33
+
34
+ ## API Signature
35
+
36
+ ### Properties
37
+
38
+ <TSDoc
39
+ definition={`
40
+ interface ThrottleError {
41
+ /** The number of seconds to wait before retrying. Present when the server sends a Retry-After header. */
42
+ retryAfter?: number;
43
+ /** The error message. */
44
+ message: string;
45
+ }
46
+ export default ThrottleError;`}
47
+ />
48
+
49
+ ### Static Methods
50
+
51
+ #### `ThrottleError.is(value)`
52
+
53
+ Type-safe check for `ThrottleError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
54
+
55
+ ```typescript
56
+ import { ThrottleError } from "workflow/errors"
57
+ declare const error: unknown; // @setup
58
+
59
+ if (ThrottleError.is(error)) {
60
+ // error is typed as ThrottleError
61
+ }
62
+ ```
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: TooEarlyError
3
+ description: Thrown when a request is made before the system is ready to process it.
4
+ type: reference
5
+ summary: Catch TooEarlyError when a world operation is attempted before the system is ready.
6
+ related:
7
+ - /docs/api-reference/workflow-errors/workflow-world-error
8
+ - /docs/api-reference/workflow-errors/throttle-error
9
+ ---
10
+
11
+ `TooEarlyError` is thrown by world implementations when a request is made before the system is ready to process it. It corresponds to HTTP 425 Too Early semantics.
12
+
13
+ The `retryAfter` property contains the number of seconds to wait before retrying.
14
+
15
+ <Callout>
16
+ The Workflow runtime handles this error automatically by retrying after the specified delay. You will only encounter it when interacting with world storage APIs directly.
17
+ </Callout>
18
+
19
+ ```typescript lineNumbers
20
+ import { TooEarlyError } from "workflow/errors"
21
+ declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
22
+ declare const runId: string; // @setup
23
+ declare const event: any; // @setup
24
+
25
+ try {
26
+ await world.events.create(runId, event);
27
+ } catch (error) {
28
+ if (TooEarlyError.is(error)) { // [!code highlight]
29
+ console.log(`Retry after ${error.retryAfter} seconds`);
30
+ }
31
+ }
32
+ ```
33
+
34
+ ## API Signature
35
+
36
+ ### Properties
37
+
38
+ <TSDoc
39
+ definition={`
40
+ interface TooEarlyError {
41
+ /** Delay in seconds before the operation can be retried. Present when the server sends a Retry-After header. */
42
+ retryAfter?: number;
43
+ /** The error message. */
44
+ message: string;
45
+ }
46
+ export default TooEarlyError;`}
47
+ />
48
+
49
+ ### Static Methods
50
+
51
+ #### `TooEarlyError.is(value)`
52
+
53
+ Type-safe check for `TooEarlyError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
54
+
55
+ ```typescript
56
+ import { TooEarlyError } from "workflow/errors"
57
+ declare const error: unknown; // @setup
58
+
59
+ if (TooEarlyError.is(error)) {
60
+ // error is typed as TooEarlyError
61
+ }
62
+ ```
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: WorkflowNotRegisteredError
3
+ description: Thrown when a workflow function is not registered in the current deployment.
4
+ type: reference
5
+ summary: Catch WorkflowNotRegisteredError when a workflow function cannot be found during execution.
6
+ related:
7
+ - /docs/errors/workflow-not-registered
8
+ - /docs/api-reference/workflow-errors/step-not-registered-error
9
+ ---
10
+
11
+ `WorkflowNotRegisteredError` is thrown when the runtime tries to execute a workflow function that is not registered in the current deployment. This is an infrastructure error — not a user code error. It typically means a run was started against a deployment that does not have this workflow (e.g., the workflow was renamed or moved), or there was a build/bundling issue.
12
+
13
+ When this error occurs, the run fails with a `RUNTIME_ERROR` error code.
14
+
15
+ ```typescript lineNumbers
16
+ import { WorkflowNotRegisteredError } from "workflow/errors"
17
+ declare const error: unknown; // @setup
18
+
19
+ if (WorkflowNotRegisteredError.is(error)) { // [!code highlight]
20
+ console.error("Workflow not registered:", error.workflowName);
21
+ }
22
+ ```
23
+
24
+ ## API Signature
25
+
26
+ ### Properties
27
+
28
+ <TSDoc
29
+ definition={`
30
+ interface WorkflowNotRegisteredError {
31
+ /** The name of the workflow function that was not found. */
32
+ workflowName: string;
33
+ /** The error message. */
34
+ message: string;
35
+ }
36
+ export default WorkflowNotRegisteredError;`}
37
+ />
38
+
39
+ ### Static Methods
40
+
41
+ #### `WorkflowNotRegisteredError.is(value)`
42
+
43
+ Type-safe check for `WorkflowNotRegisteredError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
44
+
45
+ <Callout>
46
+ The `.is()` method works in server-side Node.js code (API routes, middleware). When checking the error from `run.returnValue`, use `WorkflowRunFailedError.is()` and inspect `error.cause` — the underlying error is deserialized from the event log.
47
+ </Callout>
48
+
49
+ ```typescript
50
+ import { WorkflowNotRegisteredError } from "workflow/errors"
51
+ declare const error: unknown; // @setup
52
+
53
+ if (WorkflowNotRegisteredError.is(error)) {
54
+ // error is typed as WorkflowNotRegisteredError
55
+ }
56
+ ```
57
+
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: WorkflowRunCancelledError
3
+ description: Thrown when awaiting the return value of a cancelled workflow run.
4
+ type: reference
5
+ summary: Catch WorkflowRunCancelledError when awaiting run.returnValue on a run that was cancelled.
6
+ related:
7
+ - /docs/api-reference/workflow-errors/workflow-run-failed-error
8
+ - /docs/api-reference/workflow-errors/workflow-run-not-found-error
9
+ ---
10
+
11
+ `WorkflowRunCancelledError` is thrown when awaiting `run.returnValue` on a workflow run that was explicitly cancelled via `run.cancel()`. Cancelled runs do not produce a return value.
12
+
13
+ You can check for cancellation before awaiting by inspecting `run.status`.
14
+
15
+ ```typescript lineNumbers
16
+ import { WorkflowRunCancelledError } from "workflow/errors"
17
+ declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
18
+
19
+ try {
20
+ const result = await run.returnValue;
21
+ } catch (error) {
22
+ if (WorkflowRunCancelledError.is(error)) { // [!code highlight]
23
+ console.log(`Run ${error.runId} was cancelled`);
24
+ }
25
+ }
26
+ ```
27
+
28
+ ## API Signature
29
+
30
+ ### Properties
31
+
32
+ <TSDoc
33
+ definition={`
34
+ interface WorkflowRunCancelledError {
35
+ /** The ID of the cancelled run. */
36
+ runId: string;
37
+ /** The error message. */
38
+ message: string;
39
+ }
40
+ export default WorkflowRunCancelledError;`}
41
+ />
42
+
43
+ ### Static Methods
44
+
45
+ #### `WorkflowRunCancelledError.is(value)`
46
+
47
+ Type-safe check for `WorkflowRunCancelledError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
48
+
49
+ ```typescript
50
+ import { WorkflowRunCancelledError } from "workflow/errors"
51
+ declare const error: unknown; // @setup
52
+
53
+ if (WorkflowRunCancelledError.is(error)) {
54
+ // error is typed as WorkflowRunCancelledError
55
+ }
56
+ ```
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: WorkflowRunFailedError
3
+ description: Thrown when awaiting the return value of a failed workflow run.
4
+ type: reference
5
+ summary: Catch WorkflowRunFailedError when awaiting run.returnValue on a run that encountered a fatal error.
6
+ related:
7
+ - /docs/api-reference/workflow/fatal-error
8
+ - /docs/api-reference/workflow-errors/workflow-run-cancelled-error
9
+ - /docs/api-reference/workflow-errors/workflow-run-not-found-error
10
+ ---
11
+
12
+ `WorkflowRunFailedError` is thrown when awaiting `run.returnValue` on a workflow run whose status is `'failed'`. This indicates that the workflow encountered a fatal error during execution and cannot produce a return value.
13
+
14
+ The `cause` property contains the underlying error with its message, stack trace, and optional error code.
15
+
16
+ ```typescript lineNumbers
17
+ import { WorkflowRunFailedError } from "workflow/errors"
18
+ declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
19
+
20
+ try {
21
+ const result = await run.returnValue;
22
+ } catch (error) {
23
+ if (WorkflowRunFailedError.is(error)) { // [!code highlight]
24
+ console.error(`Run ${error.runId} failed:`, error.cause.message);
25
+ if (error.cause.code) {
26
+ console.error("Error code:", error.cause.code);
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## API Signature
33
+
34
+ ### Properties
35
+
36
+ <TSDoc
37
+ definition={`
38
+ interface WorkflowRunFailedError {
39
+ /** The ID of the failed run. */
40
+ runId: string;
41
+ /** The underlying error that caused the failure. */
42
+ cause: Error & { code?: string };
43
+ /** The error message. */
44
+ message: string;
45
+ }
46
+ export default WorkflowRunFailedError;`}
47
+ />
48
+
49
+ ### Static Methods
50
+
51
+ #### `WorkflowRunFailedError.is(value)`
52
+
53
+ Type-safe check for `WorkflowRunFailedError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
54
+
55
+ ```typescript
56
+ import { WorkflowRunFailedError } from "workflow/errors"
57
+ declare const error: unknown; // @setup
58
+
59
+ if (WorkflowRunFailedError.is(error)) {
60
+ // error is typed as WorkflowRunFailedError
61
+ }
62
+ ```
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: WorkflowRunNotFoundError
3
+ description: Thrown when operating on a workflow run that does not exist.
4
+ type: reference
5
+ summary: Catch WorkflowRunNotFoundError when performing operations on a non-existent workflow run.
6
+ related:
7
+ - /docs/api-reference/workflow-errors/workflow-run-failed-error
8
+ - /docs/api-reference/workflow-errors/workflow-run-cancelled-error
9
+ ---
10
+
11
+ `WorkflowRunNotFoundError` is thrown when performing operations on a workflow run that does not exist. This includes calling methods like `run.status`, `run.cancel()`, or awaiting `run.returnValue` on a run whose ID does not match any known workflow run.
12
+
13
+ Note that `getRun(id)` itself is synchronous and will not throw — the error is raised when subsequent operations on the run object discover the run is missing.
14
+
15
+ ```typescript lineNumbers
16
+ import { WorkflowRunNotFoundError } from "workflow/errors"
17
+ declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
18
+
19
+ try {
20
+ const status = await run.status;
21
+ } catch (error) {
22
+ if (WorkflowRunNotFoundError.is(error)) { // [!code highlight]
23
+ console.error(`Run ${error.runId} does not exist`);
24
+ }
25
+ }
26
+ ```
27
+
28
+ ## API Signature
29
+
30
+ ### Properties
31
+
32
+ <TSDoc
33
+ definition={`
34
+ interface WorkflowRunNotFoundError {
35
+ /** The ID of the run that was not found. */
36
+ runId: string;
37
+ /** The error message. */
38
+ message: string;
39
+ }
40
+ export default WorkflowRunNotFoundError;`}
41
+ />
42
+
43
+ ### Static Methods
44
+
45
+ #### `WorkflowRunNotFoundError.is(value)`
46
+
47
+ Type-safe check for `WorkflowRunNotFoundError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
48
+
49
+ ```typescript
50
+ import { WorkflowRunNotFoundError } from "workflow/errors"
51
+ declare const error: unknown; // @setup
52
+
53
+ if (WorkflowRunNotFoundError.is(error)) {
54
+ // error is typed as WorkflowRunNotFoundError
55
+ }
56
+ ```
@@ -0,0 +1,79 @@
1
+ ---
2
+ title: WorkflowWorldError
3
+ description: Base error for failures from workflow storage backends.
4
+ type: reference
5
+ summary: Catch WorkflowWorldError to handle any error originating from a workflow world (storage backend).
6
+ related:
7
+ - /docs/api-reference/workflow-errors/entity-conflict-error
8
+ - /docs/api-reference/workflow-errors/run-expired-error
9
+ - /docs/api-reference/workflow-errors/too-early-error
10
+ - /docs/api-reference/workflow-errors/throttle-error
11
+ ---
12
+
13
+ `WorkflowWorldError` is the base error class for failures originating from a workflow world (storage backend). World implementations (local, Postgres, Vercel) throw subclasses of this error when storage operations fail.
14
+
15
+ You can use `instanceof WorkflowWorldError` to catch any world-related error regardless of the specific type. Note that the static `.is()` method only matches errors constructed directly as `WorkflowWorldError` — use the subclass-specific `.is()` methods (e.g. `EntityConflictError.is()`) to match specific error types.
16
+
17
+ <Callout>
18
+ Most world errors are handled automatically by the Workflow runtime. You will typically only encounter these errors when interacting with world storage APIs directly or when there are infrastructure-level issues.
19
+ </Callout>
20
+
21
+ ```typescript lineNumbers
22
+ import { WorkflowWorldError } from "workflow/errors"
23
+ declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
24
+ declare const runId: string; // @setup
25
+ declare const event: any; // @setup
26
+
27
+ try {
28
+ await world.events.create(runId, event);
29
+ } catch (error) {
30
+ if (error instanceof WorkflowWorldError) { // [!code highlight]
31
+ console.error("Storage backend error:", error.message);
32
+ }
33
+ }
34
+ ```
35
+
36
+ ## API Signature
37
+
38
+ ### Properties
39
+
40
+ <TSDoc
41
+ definition={`
42
+ interface WorkflowWorldError {
43
+ /** HTTP status code from the world backend, if available. */
44
+ status?: number;
45
+ /** Machine-readable error code, if available. */
46
+ code?: string;
47
+ /** The URL that was requested, if available. */
48
+ url?: string;
49
+ /** Retry-After value in seconds, present on 429 and 425 responses. */
50
+ retryAfter?: number;
51
+ /** The error message. */
52
+ message: string;
53
+ }
54
+ export default WorkflowWorldError;`}
55
+ />
56
+
57
+ ### Static Methods
58
+
59
+ #### `WorkflowWorldError.is(value)`
60
+
61
+ Type-safe check that matches only errors constructed directly as `WorkflowWorldError`. Does not match subclasses like `EntityConflictError` — use `instanceof` to catch all world errors, or the subclass-specific `.is()` methods.
62
+
63
+ ```typescript
64
+ import { WorkflowWorldError } from "workflow/errors"
65
+ declare const error: unknown; // @setup
66
+
67
+ if (WorkflowWorldError.is(error)) {
68
+ // error is typed as WorkflowWorldError (not subclasses)
69
+ }
70
+ ```
71
+
72
+ ### Subclasses
73
+
74
+ The following error types extend `WorkflowWorldError`:
75
+
76
+ - [`EntityConflictError`](/docs/api-reference/workflow-errors/entity-conflict-error) — operation conflicts with entity state
77
+ - [`RunExpiredError`](/docs/api-reference/workflow-errors/run-expired-error) — run has expired
78
+ - [`TooEarlyError`](/docs/api-reference/workflow-errors/too-early-error) — request made before system is ready
79
+ - [`ThrottleError`](/docs/api-reference/workflow-errors/throttle-error) — request was rate-limited
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Changelog
3
+ description: Latest updates and new features in Workflow DevKit.
4
+ type: overview
5
+ ---
6
+
7
+ # Changelog
8
+
9
+ Stay up to date with the latest changes to Workflow DevKit.
10
+
11
+ ---
12
+
13
+ ## 2026
14
+
15
+ - TBD
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Changelog",
3
+ "pages": ["index", "eager-processing"],
4
+ "defaultOpen": false
5
+ }
@@ -180,11 +180,31 @@ interface Streamer {
180
180
  ): Promise<ReadableStream<Uint8Array>>;
181
181
 
182
182
  listStreamsByRunId(runId: string): Promise<string[]>;
183
+
184
+ /** Paginated snapshot of stream chunks. */
185
+ getStreamChunks(
186
+ name: string,
187
+ runId: string,
188
+ options?: { limit?: number; cursor?: string }
189
+ ): Promise<{
190
+ data: { index: number; data: Uint8Array }[];
191
+ cursor: string | null;
192
+ hasMore: boolean;
193
+ done: boolean;
194
+ }>;
195
+
196
+ /** Lightweight metadata: tail index and completion flag. */
197
+ getStreamInfo(
198
+ name: string,
199
+ runId: string
200
+ ): Promise<{ tailIndex: number; done: boolean }>;
183
201
  }
184
202
  ```
185
203
 
186
204
  Streams are identified by a combination of `runId` and `name`. Each workflow run can have multiple named streams.
187
205
 
206
+ `getStreamChunks` returns a paginated snapshot of currently available chunks (unlike `readFromStream` which returns a live `ReadableStream` that waits for new chunks). `getStreamInfo` returns the tail index (last chunk index, 0-based, or `-1` when empty) and whether the stream is complete — useful for resolving negative `startIndex` values into absolute positions.
207
+
188
208
  ## Reference Implementations
189
209
 
190
210
  Study these implementations for guidance:
@@ -46,6 +46,8 @@ export async function processPayment() {
46
46
  **Solution:** Use unique tokens that include the run ID or other unique identifiers.
47
47
 
48
48
  ```typescript lineNumbers
49
+ import { createHook } from "workflow";
50
+
49
51
  export async function processPayment(orderId: string) {
50
52
  "use workflow";
51
53
 
@@ -60,6 +62,8 @@ export async function processPayment(orderId: string) {
60
62
  The safest approach is to let the Workflow runtime generate a unique token automatically:
61
63
 
62
64
  ```typescript lineNumbers
65
+ import { createHook } from "workflow";
66
+
63
67
  export async function processPayment() {
64
68
  "use workflow";
65
69
 
@@ -71,10 +75,11 @@ export async function processPayment() {
71
75
 
72
76
  ## Handling Hook Conflicts in Your Workflow
73
77
 
74
- When a hook conflict occurs, awaiting the hook will throw a `WorkflowRuntimeError`. You can catch this error to handle the conflict gracefully:
78
+ When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. You can catch this error to handle the conflict gracefully:
75
79
 
76
80
  ```typescript lineNumbers
77
- import { WorkflowRuntimeError } from "@workflow/errors";
81
+ import { createHook } from "workflow";
82
+ import { HookConflictError } from "@workflow/errors";
78
83
 
79
84
  export async function processPayment(orderId: string) {
80
85
  "use workflow";
@@ -85,8 +90,9 @@ export async function processPayment(orderId: string) {
85
90
  const payment = await hook; // [!code highlight]
86
91
  return { success: true, payment };
87
92
  } catch (error) {
88
- if (error instanceof WorkflowRuntimeError && error.message.includes("hook-conflict")) { // [!code highlight]
93
+ if (HookConflictError.is(error)) { // [!code highlight]
89
94
  // Another workflow is already processing this order
95
+ console.log(`Conflicting token: ${error.token}`);
90
96
  return { success: false, reason: "duplicate-processing" };
91
97
  }
92
98
  throw error; // Re-throw other errors
@@ -37,6 +37,12 @@ Fix common mistakes when creating and executing workflows in the **Workflow DevK
37
37
  <Card href="/docs/errors/corrupted-event-log" title="corrupted-event-log">
38
38
  Learn how to handle corrupted or invalid event logs.
39
39
  </Card>
40
+ <Card href="/docs/errors/step-not-registered" title="step-not-registered">
41
+ Resolve step not registered errors caused by deployment mismatches.
42
+ </Card>
43
+ <Card href="/docs/errors/workflow-not-registered" title="workflow-not-registered">
44
+ Resolve workflow not registered errors caused by deployment mismatches.
45
+ </Card>
40
46
  </Cards>
41
47
 
42
48
  ## Learn More
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: step-not-registered
3
+ description: A step function is not registered in the current deployment.
4
+ type: troubleshooting
5
+ summary: Resolve step not registered errors caused by build issues.
6
+ prerequisites:
7
+ - /docs/foundations/steps
8
+ related:
9
+ - /docs/errors/workflow-not-registered
10
+ - /docs/api-reference/workflow-errors/step-not-registered-error
11
+ ---
12
+
13
+ This error occurs when the Workflow runtime tries to execute a step function that is not registered in the current deployment. When this happens, the step fails (like a `FatalError`) and control is passed back to the workflow function, which can optionally handle the failure.
14
+
15
+ ## Error Message
16
+
17
+ ```
18
+ Step "<stepName>" is not registered in the current deployment.
19
+ This usually indicates a build or bundling issue that caused the step
20
+ to not be included in the deployment.
21
+ ```
22
+
23
+ ## Why This Happens
24
+
25
+ Workflow runs are pegged to a specific deployment, so this error is not caused by newer deployments overriding the running code. Instead, it means the step function was not included in the deployment's workflow bundle at build time.
26
+
27
+ This is an **infrastructure error**, not a user code error.
28
+
29
+ ## Common Causes
30
+
31
+ ### Build tooling issue
32
+
33
+ Something went wrong during the build process that caused the step function to not be included in the workflow bundle. Check your build logs for errors related to workflow bundling. Common issues include:
34
+
35
+ - The step file is missing a valid `"use step"` directive
36
+ - The step function is not exported from the workflow file
37
+ - An esbuild or SWC plugin error silently excluded the step
38
+
39
+ ### Step removed from the codebase
40
+
41
+ The step function was deleted or its `"use step"` directive was removed, but the workflow still references it. Ensure all steps referenced by your workflow are present in the codebase.
42
+
43
+ ## How to Resolve
44
+
45
+ 1. **Check your build logs:** Look for errors or warnings related to workflow bundling. Ensure the step file contains a valid `"use step"` directive and is properly exported.
46
+
47
+ 2. **Verify the step exists:** Confirm the step function is present in the workflow file and has the `"use step"` directive.
48
+
49
+ 3. **Handle it in your workflow:** Since the step fails like a `FatalError`, you can catch it in your workflow code:
50
+
51
+ ```typescript lineNumbers
52
+ declare function processPayment(orderId: string): Promise<any>; // @setup
53
+
54
+ export async function myWorkflow() {
55
+ "use workflow";
56
+
57
+ try {
58
+ const result = await processPayment("order-123");
59
+ return { success: true, result };
60
+ } catch (error) {
61
+ // Step failure (including not registered) is caught here
62
+ console.error("Step failed:", error);
63
+ return { success: false, error: String(error) };
64
+ }
65
+ }
66
+ ```