Skip to content

Conversation

@pranaygp
Copy link
Collaborator

@pranaygp pranaygp commented Nov 8, 2025

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:

@changeset-bot
Copy link

changeset-bot bot commented Nov 8, 2025

🦋 Changeset detected

Latest commit: e6e749e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
@workflow/world-local Patch
@workflow/web-shared Patch
@workflow/core Patch
@workflow/world-postgres Patch
@workflow/errors Patch
@workflow/world Patch
@workflow/world-vercel Patch
@workflow/cli Patch
@workflow/builders Patch
@workflow/next Patch
@workflow/nitro Patch
workflow Patch
@workflow/world-testing Patch
@workflow/sveltekit Patch
@workflow/nuxt Patch
@workflow/ai Patch

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

@vercel
Copy link
Contributor

vercel bot commented Nov 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
example-nextjs-workflow-turbopack Ready Ready Preview Comment Nov 11, 2025 11:23pm
example-nextjs-workflow-webpack Ready Ready Preview Comment Nov 11, 2025 11:23pm
example-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workbench-hono-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workbench-nitro-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workbench-nuxt-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workbench-sveltekit-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workbench-vite-workflow Ready Ready Preview Comment Nov 11, 2025 11:23pm
workflow-docs Ready Ready Preview Comment Nov 11, 2025 11:23pm

@pranaygp pranaygp force-pushed the copilot/fix-sourcemap-tracking branch from 3ffca64 to 9a850c8 Compare November 8, 2025 17:28
@pranaygp pranaygp force-pushed the pranaygp/proper-error-stack-propogation branch from b8b3245 to ba2e061 Compare November 8, 2025 17:28
Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

Result:

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>'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

Result:

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>'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

Result:

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>'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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/core

Result:

@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.

Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.

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.

Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Copy link
Contributor

@vercel vercel bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 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 build

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'.
Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants