Skip to content

feat: workflow try helpers & visualizer support#4413

Merged
NathanFlurry merged 7 commits intomainfrom
workflow-try-step-api
Mar 31, 2026
Merged

feat: workflow try helpers & visualizer support#4413
NathanFlurry merged 7 commits intomainfrom
workflow-try-step-api

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Adds ctx.tryStep() and ctx.try() to the workflow engine and RivetKit wrapper so workflows can recover from terminal step, join, and race failures without swallowing scheduler control flow. It also updates the workflow visualizer to render named try scopes and handled failures, plus adds docs, stories, and integration coverage for the new behavior.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • pnpm exec vitest run tests/try.test.ts tests/join.test.ts tests/race.test.ts in rivetkit-typescript/packages/workflow-engine
  • pnpm exec vitest run tests/driver-memory.test.ts -t "tryStep and try recover terminal workflow failures" in rivetkit-typescript/packages/rivetkit
  • pnpm test workflow-to-xyflow in frontend
  • pnpm exec biome check src/components/actors/workflow/workflow-to-xyflow.ts src/components/actors/workflow/workflow-to-xyflow.test.ts src/components/actors/workflow/xyflow-nodes.tsx src/components/actors/workflow/workflow-visualizer.tsx src/components/actors/workflow/workflow-example-data.ts src/components/actors/workflow/xyflow-nodes.stories.tsx in frontend

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 13, 2026 04:30 Destroyed
@railway-app
Copy link
Copy Markdown

railway-app bot commented Mar 13, 2026

🚅 Deployed to the rivet-pr-4413 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-cloud 😴 Sleeping (View Logs) Web Mar 31, 2026 at 12:03 am
website 😴 Sleeping (View Logs) Web Mar 31, 2026 at 12:03 am
frontend-inspector 😴 Sleeping (View Logs) Web Mar 31, 2026 at 12:02 am
mcp-hub ✅ Success (View Logs) Web Mar 30, 2026 at 11:51 pm
ladle ❌ Build Failed (View Logs) Web Mar 30, 2026 at 11:51 pm

@NathanFlurry
Copy link
Copy Markdown
Member Author

Screenshots relevant to the workflow try UI changes:

Workflow try control flow

Workflow try handled failures

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 13, 2026

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@4413

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4413

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4413

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4413

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4413

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4413

@rivetkit/sqlite-vfs

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@4413

@rivetkit/traces

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@4413

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4413

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4413

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4413

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4413

commit: ef43f37

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 13, 2026 04:35 Destroyed
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 13, 2026 04:41 Destroyed
@claude
Copy link
Copy Markdown

claude bot commented Mar 13, 2026

PR Review: feat: workflow try helpers and visualizer support. This PR adds ctx.tryStep() and ctx.try() to the workflow engine for recovering from terminal failures without disrupting scheduler control flow, plus visualizer and docs support. The design is solid overall with some items worth addressing. CORRECTNESS: Bug fix in race winner detection: The old winnerValue !== null check would incorrectly skip returning when a branch legitimately yields null. The new hasWinner boolean flag is the right fix. Scheduler yield propagation in join/race branches: The new mergeSchedulerYield / selectControlFlowError plumbing correctly handles retrying steps inside join/race branches, which previously could corrupt branch state by marking a retrying branch as failed. markErrorReported + attachTryStepFailure chaining: Both helpers mutate the error in-place and return it, so chaining markErrorReported(attachTryStepFailure(err, ...)) correctly preserves both Symbol properties on the same object. ISSUES: 1. parseStoredWorkflowError vs extractErrorInfo inconsistency: getTryStepFailureFromExhaustedError uses parseStoredWorkflowError(error.lastError) while every other failure builder uses extractErrorInfo(liveError). The two paths produce subtly different results as extractErrorInfo also captures stack and enumerable metadata while parseStoredWorkflowError only gets name/message. A comment explaining why the string-parse path is needed here would prevent future confusion. 2. TryBlockFailure.source maps to TryBlockCatchKind inconsistently: In shouldCatchTryBlockFailure, a RollbackError thrown directly inside a ctx.try block gets source block, but users must put rollback in their catch list to intercept it. The mismatch between the source name and the catch kind will surprise callers. Consider renaming source block to source rollback, or adding an explicit block catch kind. 3. Missing guard when run is not passed to the string-overload of tryStep: The non-null assertion run! silently passes undefined at runtime if the caller forgets the second argument. The ctx.try wrapper already throws explicitly. Consider adding the same guard to tryStep string overload. 4. Step rollback inside ctx.try requires rollback in catch, but other step failures only require step: DEFAULT_TRY_BLOCK_CATCH does not catch rollback-kind step failures. This is intentional since rollbacks signal programmer errors, but it is a sharp edge not mentioned in the docs or QUICKSTART.md. A single sentence noting this distinction would prevent confusion. NITS: 5. Missing comment on new HistoryDivergedError guards: The new if (!branchStatus) checks in join/race are correct defensive guards. A short comment noting that this triggers when the workflow definition changes between runs would help. 6. No test for nested ctx.try inside ctx.try: Nested try blocks are a worthwhile edge case to add. TEST COVERAGE: try.test.ts covers the main happy and sad paths well. The additions to join.test.ts and race.test.ts for retry-within-branch correctness are particularly valuable since those fixed real bugs. The integration test in actor-workflow.ts closes the loop at the RivetKit layer. SUMMARY: The core design is clean and the scheduler yield refactor in join/race is a genuine improvement. Items 2 and 4 are the most likely to cause real user confusion and are worth addressing before merge.

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 13, 2026 04:49 Destroyed
@NathanFlurry
Copy link
Copy Markdown
Member Author

Updated workflow UI screenshots after the alignment polish:

Full canvas:
workflow try control flow latest

Try header close-up:
workflow try header closeup

Failed node close-up:
workflow failed node closeup

@NathanFlurry NathanFlurry requested a review from jog1t March 20, 2026 22:43
@NathanFlurry NathanFlurry changed the title Add workflow try helpers and visualizer support feat: workflow try helpers & visualizer support Mar 20, 2026
@NathanFlurry NathanFlurry force-pushed the workflow-try-step-api branch from 000ae2a to c58143b Compare March 21, 2026 01:59
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 21, 2026 01:59 Destroyed
@NathanFlurry NathanFlurry changed the base branch from main to graphite-base/4413 March 30, 2026 23:50
@NathanFlurry NathanFlurry force-pushed the workflow-try-step-api branch from f92fb2f to 08d9f1e Compare March 30, 2026 23:50
@NathanFlurry NathanFlurry changed the base branch from graphite-base/4413 to workflow-step-resume March 30, 2026 23:50
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 30, 2026 23:50 Destroyed
Copy link
Copy Markdown
Member Author

NathanFlurry commented Mar 30, 2026

@NathanFlurry NathanFlurry force-pushed the workflow-step-resume branch 2 times, most recently from 8fb8fed to 769e543 Compare March 31, 2026 01:12
@NathanFlurry NathanFlurry force-pushed the workflow-try-step-api branch from 08d9f1e to ef43f37 Compare March 31, 2026 01:12
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 31, 2026 01:13 Destroyed
@NathanFlurry NathanFlurry changed the base branch from workflow-step-resume to graphite-base/4413 March 31, 2026 01:14
@NathanFlurry NathanFlurry force-pushed the workflow-try-step-api branch from ef43f37 to 022a7a3 Compare March 31, 2026 01:14
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4413 March 31, 2026 01:14 Destroyed
@graphite-app graphite-app bot changed the base branch from graphite-base/4413 to main March 31, 2026 01:14
@NathanFlurry NathanFlurry force-pushed the workflow-try-step-api branch from 022a7a3 to fe2bd86 Compare March 31, 2026 01:15
@NathanFlurry NathanFlurry merged commit b1a2d55 into main Mar 31, 2026
15 of 19 checks passed
Copy link
Copy Markdown
Member Author

Merge activity

@NathanFlurry NathanFlurry deleted the workflow-try-step-api branch March 31, 2026 01:17
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.

1 participant