diff --git a/.changeset/lazy-terminal-run-data.md b/.changeset/lazy-terminal-run-data.md new file mode 100644 index 0000000000..17ee9e1daf --- /dev/null +++ b/.changeset/lazy-terminal-run-data.md @@ -0,0 +1,6 @@ +--- +"@workflow/world": patch +"@workflow/core": patch +--- + +Accept lazy completed and failed runs whose payload is represented by a remote reference. diff --git a/packages/core/src/runtime/run.ts b/packages/core/src/runtime/run.ts index 02a6459a70..f7488766b5 100644 --- a/packages/core/src/runtime/run.ts +++ b/packages/core/src/runtime/run.ts @@ -291,7 +291,12 @@ export class Run { } if (run.status === 'failed') { - throw new WorkflowRunFailedError(this.runId, run.error); + // Terminal run data can be returned lazily, so the error payload + // may not be materialized. Fall back to a generic message. + throw new WorkflowRunFailedError( + this.runId, + run.error ?? { message: 'Workflow run failed' } + ); } throw new WorkflowRunNotCompletedError(this.runId, run.status); diff --git a/packages/world/src/runs.test.ts b/packages/world/src/runs.test.ts new file mode 100644 index 0000000000..e4d912808b --- /dev/null +++ b/packages/world/src/runs.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest'; +import { z } from 'zod'; +import { WorkflowRunSchema } from './runs.js'; + +describe('WorkflowRunSchema', () => { + it('accepts terminal runs without materialized payloads', () => { + const completedSchema = WorkflowRunSchema.options[2]; + const failedSchema = WorkflowRunSchema.options[3]; + const run = { + runId: 'wrun_1', + deploymentId: 'dpl_1', + workflowName: 'workflow_1', + createdAt: new Date(), + updatedAt: new Date(), + completedAt: new Date(), + }; + + expect(completedSchema.shape.output).toBeInstanceOf(z.ZodOptional); + expect(failedSchema.shape.error).toBeInstanceOf(z.ZodOptional); + expect( + WorkflowRunSchema.safeParse({ ...run, status: 'completed' }).success + ).toBe(true); + expect( + WorkflowRunSchema.safeParse({ ...run, status: 'failed' }).success + ).toBe(true); + }); +}); diff --git a/packages/world/src/runs.ts b/packages/world/src/runs.ts index 248bbe1176..989c2eb021 100644 --- a/packages/world/src/runs.ts +++ b/packages/world/src/runs.ts @@ -99,7 +99,7 @@ export const WorkflowRunSchema = z.discriminatedUnion('status', [ // Completed state - output can be v1 or v2 format WorkflowRunBaseSchema.extend({ status: z.literal('completed'), - output: SerializedDataSchema, + output: SerializedDataSchema.optional(), error: z.undefined().optional(), completedAt: z.coerce.date(), }), @@ -107,7 +107,7 @@ export const WorkflowRunSchema = z.discriminatedUnion('status', [ WorkflowRunBaseSchema.extend({ status: z.literal('failed'), output: z.undefined().optional(), - error: StructuredErrorSchema, + error: StructuredErrorSchema.optional(), completedAt: z.coerce.date(), }), ]);