Proper error stack propogating#280
Conversation
🦋 Changeset detectedLatest commit: e6e749e The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
3ffca64 to
9a850c8
Compare
b8b3245 to
ba2e061
Compare
There was a problem hiding this comment.
🔧 Build Fix:
The attributeToDisplayFn object is missing a handler for the errorStack property, causing TypeScript to fail compilation since errorStack is included in the AttributeKey type union but not implemented in the mapping object.
View Details
📝 Patch Details
diff --git a/packages/web-shared/src/sidebar/attribute-panel.tsx b/packages/web-shared/src/sidebar/attribute-panel.tsx
index b12fbaf..073ec82 100644
--- a/packages/web-shared/src/sidebar/attribute-panel.tsx
+++ b/packages/web-shared/src/sidebar/attribute-panel.tsx
@@ -53,6 +53,7 @@ const attributeOrder: AttributeKey[] = [
'completedAt',
'retryAfter',
'error',
+ 'errorStack',
'errorCode',
'metadata',
'eventData',
@@ -125,6 +126,9 @@ const attributeToDisplayFn: Record<
error: (value: unknown) => {
return <DetailCard summary="Error">{JsonBlock(value)}</DetailCard>;
},
+ errorStack: (value: unknown) => {
+ return <DetailCard summary="Error Stack">{JsonBlock(value)}</DetailCard>;
+ },
errorCode: JsonBlock,
eventData: (value: unknown) => {
return <DetailCard summary="Event Data">{JsonBlock(value)}</DetailCard>;
@@ -135,6 +139,7 @@ const resolvableAttributes = [
'input',
'output',
'error',
+ 'errorStack',
'errorCode',
'metadata',
'eventData',
Analysis
Missing TypeScript handler for errorStack property causes compilation failure
What fails: TypeScript compiler fails on packages/web-shared/src/sidebar/attribute-panel.tsx at line 70 due to missing errorStack property handler in attributeToDisplayFn object
How to reproduce:
cd packages/web-shared && pnpm run buildResult:
src/sidebar/attribute-panel.tsx(70,7): error TS2741: Property 'errorStack' is missing in type '{ workflowName: (value: unknown) => string; stepName: (value: unknown) => string; runId: (value: unknown) => string; stepId: (value: unknown) => string; hookId: (value: unknown) => string; ... 22 more ...; eventData: (value: unknown) => JSX.Element; }' but required in type 'Record<AttributeKey, (value: unknown) => ReactNode>'.There was a problem hiding this comment.
🔧 Build Fix:
The attributeToDisplayFn record was missing a display function for the errorStack property, which is required by the TypeScript type system since errorStack is part of both Step and WorkflowRun types.
View Details
📝 Patch Details
diff --git a/packages/web-shared/src/sidebar/attribute-panel.tsx b/packages/web-shared/src/sidebar/attribute-panel.tsx
index b12fbaf..c649e4d 100644
--- a/packages/web-shared/src/sidebar/attribute-panel.tsx
+++ b/packages/web-shared/src/sidebar/attribute-panel.tsx
@@ -125,6 +125,9 @@ const attributeToDisplayFn: Record<
error: (value: unknown) => {
return <DetailCard summary="Error">{JsonBlock(value)}</DetailCard>;
},
+ errorStack: (value: unknown) => {
+ return <DetailCard summary="Error Stack">{JsonBlock(value)}</DetailCard>;
+ },
errorCode: JsonBlock,
eventData: (value: unknown) => {
return <DetailCard summary="Event Data">{JsonBlock(value)}</DetailCard>;
Analysis
Missing errorStack property causes TypeScript compilation failure
What fails: TypeScript compiler fails on packages/web-shared/src/sidebar/attribute-panel.tsx line 70 due to missing errorStack property in attributeToDisplayFn record
How to reproduce:
cd packages/web-shared && pnpm run buildResult:
src/sidebar/attribute-panel.tsx(70,7): error TS2741: Property 'errorStack' is missing in type '{ workflowName: (value: unknown) => string; stepName: (value: unknown) => string; runId: (value: unknown) => string; stepId: (value: unknown) => string; hookId: (value: unknown) => string; ... 22 more ...; eventData: (value: unknown) => JSX.Element; }' but required in type 'Record<AttributeKey, (value: unknown) => ReactNode>'.There was a problem hiding this comment.
🔧 Build Fix:
The attributeToDisplayFn object is missing the errorStack property that is required by the AttributeKey type, causing TypeScript compilation to fail.
View Details
📝 Patch Details
diff --git a/packages/web-shared/src/sidebar/attribute-panel.tsx b/packages/web-shared/src/sidebar/attribute-panel.tsx
index b12fbaf..f3bb0b4 100644
--- a/packages/web-shared/src/sidebar/attribute-panel.tsx
+++ b/packages/web-shared/src/sidebar/attribute-panel.tsx
@@ -125,6 +125,9 @@ const attributeToDisplayFn: Record<
error: (value: unknown) => {
return <DetailCard summary="Error">{JsonBlock(value)}</DetailCard>;
},
+ errorStack: (value: unknown) => {
+ return <DetailCard summary="Error Stack">{JsonBlock(value)}</DetailCard>;
+ },
errorCode: JsonBlock,
eventData: (value: unknown) => {
return <DetailCard summary="Event Data">{JsonBlock(value)}</DetailCard>;
@@ -135,6 +138,7 @@ const resolvableAttributes = [
'input',
'output',
'error',
+ 'errorStack',
'errorCode',
'metadata',
'eventData',
Analysis
Missing errorStack property in attributeToDisplayFn causes TypeScript compilation failure
What fails: TypeScript compiler fails on src/sidebar/attribute-panel.tsx at line 70 due to missing errorStack property in attributeToDisplayFn object
How to reproduce:
cd packages/web-shared && pnpm run buildResult:
src/sidebar/attribute-panel.tsx(70,7): error TS2741: Property 'errorStack' is missing in type '{ workflowName: (value: unknown) => string; stepName: (value: unknown) => string; runId: (value: unknown) => string; stepId: (value: unknown) => string; hookId: (value: unknown) => string; ... 22 more ...; eventData: (value: unknown) => JSX.Element; }' but required in type 'Record<AttributeKey, (value: unknown) => ReactNode>'.
9a850c8 to
73eeaf2
Compare
ba2e061 to
e8647fa
Compare
There was a problem hiding this comment.
Additional Suggestion:
The FatalError event data uses err.stack directly instead of the extracted errorStack variable, causing potential data loss and inconsistency with similar error handling code elsewhere.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 01fa238..74ce62e 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -750,7 +750,7 @@ export const stepEntrypoint =
correlationId: stepId,
eventData: {
error: String(err),
- stack: err.stack,
+ stack: errorStack,
fatal: true,
},
});
Analysis
Inconsistent error stack handling in FatalError event creation
What fails: In packages/core/src/runtime.ts line 753, the FatalError event uses err.stack directly instead of the extracted errorStack variable, causing potential undefined values in event data.
How to reproduce:
- Define a step that throws a non-native error object (e.g.,
throw { message: "error", isFatal: true }) - Wrap it as a FatalError in the workflow
- Trigger step execution with this non-native error
- Check the event data created by
world.events.create()
Result: The event's eventData.stack field is undefined because err.stack is undefined for non-native error objects.
Expected: The event's eventData.stack field should contain the extracted error stack (either the actual stack or an empty string), consistent with:
- Line 783:
stack: errorStack,(max retries case) - Line 818:
stack: getErrorStack(err),(retryable error case)
The getErrorStack() function in types.ts guarantees a string return (either native error stack or empty string), whereas err.stack can be undefined. The extracted errorStack variable at line 742 was already safely computed but not used in the event.
|
okay @TooTallNate I'm gonna invest the time in to simplify the world to have a single |
There was a problem hiding this comment.
🔧 Build Fix:
The build fails because the code assigns errorCode properties to WorkflowRun and Step objects, but these properties don't exist in the TypeScript schemas defined in @workflow/world.
View Details
📝 Patch Details
diff --git a/packages/world-local/src/storage.ts b/packages/world-local/src/storage.ts
index 2292832..7c99382 100644
--- a/packages/world-local/src/storage.ts
+++ b/packages/world-local/src/storage.ts
@@ -112,7 +112,6 @@ export function createStorage(basedir: string): Storage {
input: (data.input as any[]) || [],
output: undefined,
error: undefined,
- errorCode: undefined,
startedAt: undefined,
completedAt: undefined,
createdAt: now,
@@ -234,7 +233,6 @@ export function createStorage(basedir: string): Storage {
input: data.input as any[],
output: undefined,
error: undefined,
- errorCode: undefined,
attempt: 0,
startedAt: undefined,
completedAt: undefined,
Analysis
TypeScript compilation fails due to invalid errorCode properties
What fails: TypeScript compiler fails on packages/world-local/src/storage.ts due to errorCode properties not existing in the WorkflowRun and Step schemas
How to reproduce:
pnpm turbo run build --filter=@workflow/world-localResult:
src/storage.ts(115,11): error TS2353: Object literal may only specify known properties, and 'errorCode' does not exist in type '{ runId: string; deploymentId: string; status: "pending" | "running" | "completed" | "failed" | "paused" | "cancelled"; workflowName: string; input: any[]; createdAt: Date; updatedAt: Date; ... 4 more ...; completedAt?: Date | undefined; }'.
src/storage.ts(237,11): error TS2353: Object literal may only specify known properties, and 'errorCode' does not exist in type '{ runId: string; stepId: string; stepName: string; status: "pending" | "running" | "completed" | "failed" | "cancelled"; input: any[]; attempt: number; createdAt: Date; updatedAt: Date; ... 4 more ...; retryAfter?: Date | undefined; }'.| return ( | ||
| <DetailCard summary="Error"> | ||
| <pre | ||
| className="text-copy-12 overflow-x-auto rounded-md border p-4" | ||
| style={{ | ||
| borderColor: 'var(--ds-gray-300)', | ||
| backgroundColor: 'var(--ds-gray-100)', | ||
| color: 'var(--ds-gray-1000)', | ||
| whiteSpace: 'pre-wrap', | ||
| }} | ||
| > | ||
| <code>{String(value)}</code> | ||
| </pre> | ||
| </DetailCard> | ||
| ); |
There was a problem hiding this comment.
| return ( | |
| <DetailCard summary="Error"> | |
| <pre | |
| className="text-copy-12 overflow-x-auto rounded-md border p-4" | |
| style={{ | |
| borderColor: 'var(--ds-gray-300)', | |
| backgroundColor: 'var(--ds-gray-100)', | |
| color: 'var(--ds-gray-1000)', | |
| whiteSpace: 'pre-wrap', | |
| }} | |
| > | |
| <code>{String(value)}</code> | |
| </pre> | |
| </DetailCard> | |
| ); | |
| return <DetailCard summary="Error">{JsonBlock(value)}</DetailCard>; |
The error display function uses String(value) which converts StructuredError objects to [object Object] instead of displaying the actual error information.
View Details
Analysis
Error attribute displays [object Object] instead of error details in AttributePanel
What fails: The error attribute display handler in AttributePanel (packages/web-shared/src/sidebar/attribute-panel.tsx, line 136) uses String(value) on a StructuredError object, which produces [object Object] instead of displaying error information.
How to reproduce:
- Display a workflow run or step with an error status in the trace viewer
- Navigate to the Error attribute in the detail panel
- Observe the error display shows
[object Object]instead of the actual error content
Result: Error attribute displays [object Object] with no useful error information
Expected: Should display the error as formatted JSON showing the message, stack, and code properties, consistent with other complex attributes like input, output, and metadata which use JsonBlock()
Root cause: The StructuredError type (defined in packages/world/src/shared.ts as { message: string, stack?: string, code?: string }) is a plain object. When String() is called on a plain object in JavaScript, it returns [object Object]. The previous implementation used JsonBlock(value) which properly serializes the object with JSON.stringify(value, null, 2).
Fix: Changed the error handler from using String(value) wrapped in custom styling to using JsonBlock(value), which is already used for similar complex attributes (metadata, input, output, eventData).
There was a problem hiding this comment.
^ Valid feedback, but instead of taking the diff, I'd just json-serialize the error
There was a problem hiding this comment.
We would never get here if this was a structured error object though 🤔
structured error object are handled above and this is the string fallback for backwards compat no?
There was a problem hiding this comment.
If it's a structured error object or an Error instance, yes. I guess it's pretty impossible to have anything else in there, but I like the idea of being exhaustive when doing type checking. Maybe throw if we get to this code point and the value is an object. Also fine not to, it's a nit
Proper stacktrace propogation in world
| updatedAt: z.coerce.date(), | ||
| }); | ||
|
|
||
| // Discriminated union based on status |
| return ( | ||
| <DetailCard summary="Error"> | ||
| <pre | ||
| className="text-copy-12 overflow-x-auto rounded-md border p-4" | ||
| style={{ | ||
| borderColor: 'var(--ds-gray-300)', | ||
| backgroundColor: 'var(--ds-gray-100)', | ||
| color: 'var(--ds-gray-1000)', | ||
| whiteSpace: 'pre-wrap', | ||
| }} | ||
| > | ||
| <code>{String(value)}</code> | ||
| </pre> | ||
| </DetailCard> | ||
| ); |
There was a problem hiding this comment.
^ Valid feedback, but instead of taking the diff, I'd just json-serialize the error
| return ( | ||
| <DetailCard summary="Error"> | ||
| <pre | ||
| className="text-copy-12 overflow-x-auto rounded-md border p-4" |
There was a problem hiding this comment.
De-dupe with styling above by extracting component
There was a problem hiding this comment.
Okay I'll fix this in a follow up PR. the PR stack has gotten really messy with this git butler thing and everythings in a bad state so I just wanna get this merged in and fix the rest of your comments in a separate PR completely
There was a problem hiding this comment.
I'm gonna merge this if the current tests pass and then open a fix PR directly on main with more stuff
| <pre | ||
| className="text-copy-12 overflow-x-auto rounded-md border p-4" | ||
| style={{ | ||
| borderColor: 'var(--ds-gray-300)', |
There was a problem hiding this comment.
Not relevant to PR, but reminder to myself that I gotta fix these variable names to be tw classes
|
@VaguelySerious which world is that? The world code should be written in a way that's backwards compatible. Maybe I forgot to do its with local world though |
|
^ yeah local world |
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter has a type mismatch where the returned promise type includes void but the declared type only expects Date | undefined, causing TypeScript compilation to fail.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..e25a98c 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt === undefined ? undefined : run.completedAt);
}
/**
Analysis
TypeScript type mismatch in workflow run completedAt getter
What fails: TypeScript compilation fails in packages/core/src/runtime.ts at line 161 due to type mismatch in the completedAt getter
How to reproduce:
pnpm turbo build --filter=@workflow/coreResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method has a type mismatch where the return type expects Promise<Date | undefined> but the actual return includes void instead of undefined due to the discriminated union in the WorkflowRun schema.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..879d884 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,10 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ const completedAt = run.completedAt as Date | void;
+ return completedAt === undefined ? undefined : completedAt;
+ });
}
/**
Analysis
TypeScript compilation error in runtime.ts completedAt getter
What fails: TypeScript compiler fails on packages/core/src/runtime.ts:161 due to type mismatch in the completedAt getter method
How to reproduce:
pnpm turbo build --filter="@workflow/core"Result:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method returns a Promise that can contain void | Date | undefined but the method signature expects Promise<Date | undefined>. The discriminated union for WorkflowRun allows completedAt to be void for non-final workflow states, causing a TypeScript compilation error.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation failure in workflow core package
What fails: TypeScript compiler fails on packages/core/src/runtime.ts at line 161 due to type mismatch in the completedAt getter method
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter has a type mismatch because the Zod schema defines completedAt as void for non-final workflow states but Date for final states, creating a union type that doesn't match the expected Promise<Date | undefined> return type.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..8a0ea29 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,14 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ // For non-final states (pending, running, paused), completedAt is void
+ // For final states (cancelled, completed, failed), completedAt is Date
+ if (run.status === 'pending' || run.status === 'running' || run.status === 'paused') {
+ return undefined;
+ }
+ return run.completedAt as Date;
+ });
}
/**
Analysis
TypeScript compilation failure due to incompatible Promise return types
What fails: TypeScript compiler fails on packages/core/src/runtime.ts at line 161 due to incompatible Promise return types
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter returns a type that doesn't match its declared return type because the Zod schema defines completedAt as void for non-completed workflow runs, but the getter expects Date | undefined.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..390298a 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,10 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ // Handle the case where completedAt is void for non-completed runs
+ return run.completedAt instanceof Date ? run.completedAt : undefined;
+ });
}
/**
Analysis
TypeScript compilation failure due to type mismatch in WorkflowRun completedAt property
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to type incompatibility between the discriminated union schema and the getter return type
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.Root cause: The WorkflowRun schema uses discriminated unions where completedAt can be void for non-completed workflow runs (pending/running/paused status) or Date for completed runs, but the completedAt getter expected only Date | undefined.
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter returns a Promise that can include void type, but the method signature only allows Date | undefined. The issue occurs because the WorkflowRun schema defines completedAt as void for non-final states and Date for final states.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation error in runtime.ts completedAt getter
What fails: TypeScript compiler fails on src/runtime.ts(161,5) due to type mismatch in Promise return type
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter returns a Promise that includes void in its union type, but the method signature expects only Date | undefined. The discriminated union in WorkflowRun uses void for non-final states and Date for completed states, causing a TypeScript compilation error.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation failure in @workflow/core due to incompatible return type
What fails: TypeScript compilation fails on packages/core/src/runtime.ts at line 161 due to incompatible Promise return type
How to reproduce:
pnpm turbo run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method returns Promise<void | Date | undefined> but is typed to return Promise<Date | undefined>. This occurs because the WorkflowRun discriminated union allows completedAt to be void for non-final workflow states, but the getter method doesn't handle this case.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation error in WorkflowRuntime.completedAt getter
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to type mismatch in completedAt getter method
How to reproduce:
turbo run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method has a type mismatch where the return type is declared as Promise<Date | undefined> but the discriminated union WorkflowRun type includes void for non-final workflow states, causing TypeScript compilation to fail.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..8a0ea29 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,14 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ // For non-final states (pending, running, paused), completedAt is void
+ // For final states (cancelled, completed, failed), completedAt is Date
+ if (run.status === 'pending' || run.status === 'running' || run.status === 'paused') {
+ return undefined;
+ }
+ return run.completedAt as Date;
+ });
}
/**
Analysis
TypeScript compilation error in @workflow/core package
What fails: TypeScript compiler fails on packages/core/src/runtime.ts:161 due to return type mismatch in completedAt getter method
How to reproduce:
turbo run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter has a TypeScript compilation error because it returns Promise<void | Date | undefined> instead of the expected Promise<Date | undefined>. The discriminated union schema allows void values for non-final workflow states, but the getter's return type doesn't account for this.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..1164f23 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,10 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ const completedAt = run.completedAt;
+ return completedAt instanceof Date ? completedAt : undefined;
+ });
}
/**
Analysis
TypeScript compilation failure due to Promise return type mismatch
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to incompatible Promise return type in completedAt getter
How to reproduce:
npx turbo run build --filter=@workflow/coreResult:
@workflow/core:build: src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
@workflow/core:build: Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
@workflow/core:build: Type 'void' is not assignable to type 'Date | undefined'.The completedAt getter was returning run.completedAt directly, but the discriminated union schema in packages/world/src/runs.ts defines completedAt: z.void() for non-final workflow states (pending, running, paused), causing the return type to include void.
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter has a type mismatch where WorkflowRun.completedAt returns void | Date but the method signature expects Promise<Date | undefined>.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation failure in runtime.ts completedAt getter
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to type mismatch in the completedAt getter method
How to reproduce:
cd packages/core && pnpm buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.Issue: The WorkflowRun.completedAt property can be void | Date based on the discriminated union schema, but the method signature expects Promise<Date | undefined>. The void type from non-final workflow states needs to be converted to undefined.
There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method has a TypeScript type mismatch where the Zod discriminated union returns void | Date | undefined but the method signature expects Promise<Date | undefined>. The void type from non-final workflow states needs to be converted to undefined.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..b428ee2 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,7 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => run.completedAt || undefined);
}
/**
Analysis
TypeScript compilation error in completedAt getter
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to type mismatch in completedAt getter method
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter method has a type mismatch where the discriminated union type WorkflowRun.completedAt can be void | Date | undefined but the method signature expects only Promise<Date | undefined>. The void type from non-final workflow states is not assignable to Date | undefined.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..aaa772b 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,10 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ // For non-final states, completedAt is void; for final states, it's Date
+ return run.completedAt as Date | undefined;
+ });
}
/**
Analysis
TypeScript compilation failure due to discriminated union type mismatch
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to incompatible return type in completedAt getter
How to reproduce:
cd packages/core && pnpm buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.There was a problem hiding this comment.
🔧 Build Fix:
The completedAt getter returns Promise<void | Date | undefined> but is declared to return Promise<Date | undefined>. The void type from the discriminated union for non-final workflow states cannot be assigned to Date | undefined.
View Details
📝 Patch Details
diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts
index 069accb..7fe8de3 100644
--- a/packages/core/src/runtime.ts
+++ b/packages/core/src/runtime.ts
@@ -158,7 +158,9 @@ export class Run<TResult> {
* Returns undefined if the workflow has not completed yet.
*/
get completedAt(): Promise<Date | undefined> {
- return this.world.runs.get(this.runId).then((run) => run.completedAt);
+ return this.world.runs.get(this.runId).then((run) => {
+ return run.completedAt instanceof Date ? run.completedAt : undefined;
+ });
}
/**
Analysis
TypeScript compilation error in runtime.ts
What fails: TypeScript compiler fails on packages/core/src/runtime.ts line 161 due to type mismatch in the completedAt getter
How to reproduce:
cd packages/core && pnpm run buildResult:
src/runtime.ts(161,5): error TS2322: Type 'Promise<void | Date | undefined>' is not assignable to type 'Promise<Date | undefined>'.
Type 'void | Date | undefined' is not assignable to type 'Date | undefined'.
Type 'void' is not assignable to type 'Date | undefined'.
In #256 we started propogating error stacks for worklfow runs, but we just marshalled them into the error string itself. This now moves the stack propogation more correctly into the world interface instead :)
This is part 2 of 3 in a stack made with GitButler: