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.
- package/dist/api.d.ts +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -1
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +2 -2
- package/dist/observability.d.ts +20 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +20 -0
- package/docs/ai/defining-tools.mdx +6 -0
- package/docs/ai/index.mdx +3 -0
- package/docs/ai/message-queueing.mdx +2 -0
- package/docs/ai/resumable-streams.mdx +37 -4
- package/docs/ai/sleep-and-delays.mdx +2 -0
- package/docs/api-reference/meta.json +1 -1
- package/docs/api-reference/workflow/define-hook.mdx +2 -0
- package/docs/api-reference/workflow/get-writable.mdx +1 -0
- package/docs/api-reference/workflow-ai/durable-agent.mdx +2 -0
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +2 -0
- package/docs/api-reference/workflow-api/get-run.mdx +14 -0
- package/docs/api-reference/workflow-api/get-world.mdx +105 -0
- package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +90 -0
- package/docs/api-reference/workflow-errors/meta.json +16 -0
- package/docs/api-reference/workflow-errors/run-expired-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/throttle-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/too-early-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +57 -0
- package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/workflow-world-error.mdx +79 -0
- package/docs/changelog/index.mdx +15 -0
- package/docs/changelog/meta.json +5 -0
- package/docs/deploying/building-a-world.mdx +20 -0
- package/docs/errors/hook-conflict.mdx +9 -3
- package/docs/errors/index.mdx +6 -0
- package/docs/errors/step-not-registered.mdx +66 -0
- package/docs/errors/webhook-invalid-respond-with-value.mdx +10 -0
- package/docs/errors/webhook-response-not-sent.mdx +8 -0
- package/docs/errors/workflow-not-registered.mdx +64 -0
- package/docs/foundations/errors-and-retries.mdx +29 -0
- package/docs/foundations/streaming.mdx +22 -0
- package/docs/getting-started/index.mdx +3 -3
- package/docs/getting-started/meta.json +15 -0
- package/docs/getting-started/nestjs.mdx +4 -8
- 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
|
|
@@ -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 `
|
|
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 {
|
|
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 (
|
|
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
|
package/docs/errors/index.mdx
CHANGED
|
@@ -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
|
+
```
|