<Branch>.
Retries
Set theretries prop to retry a task on failure. The value is the number of additional attempts after the first failure (so retries={2} means up to 3 total attempts):
_smithers_attempts. Previous attempts are never overwritten. Between the failure and the next attempt, a NodeRetrying event is emitted.
The task is marked failed only after all retries are exhausted.
Schema validation retries
Schema validation failures have their own retry mechanism, separate from theretries prop. When the agent returns JSON that does not match the output schema, Smithers sends up to 2 follow-up prompts with the validation errors appended. These schema retries happen within a single attempt — they do not consume a retries count.
If schema retries also fail, the attempt fails and the retries mechanism takes over (if configured).
Timeouts
SettimeoutMs to limit how long a single attempt can take:
retries is set, the task will retry. This is useful for guarding against agent calls that hang indefinitely.
continueOnFail
By default, when a task fails (after exhausting all retries), the workflow stops. SetcontinueOnFail to allow subsequent tasks to proceed:
continueOnFail, the report task will execute even if optional-lint fails. The failed task’s node state is failed, but the workflow continues.
This is useful for non-critical steps like linting, optional analysis passes, or telemetry tasks.
skipIf
SetskipIf to conditionally skip a task at render time:
skipIf evaluates to true, the task is marked skipped immediately. It will not run even if the condition changes on a later render cycle.
Important: skipIf is evaluated during rendering, not during execution. For tasks that should only run after a prerequisite completes, use conditional rendering with ctx.outputMaybe() instead:
Branch for Error Recovery
Use<Branch> to route execution based on the outcome of a previous task. This is the primary pattern for fallback paths:
<Branch> component evaluates its if prop at render time. On the first render, risky is undefined so ok is false — but the risky task runs first because it appears earlier in the <Sequence>. After risky completes, the workflow re-renders, ok resolves to the actual value, and the appropriate branch is taken.
Combining Patterns
Here is a workflow that combines multiple error handling patterns:Error Handling Summary
| Mechanism | Prop | Effect |
|---|---|---|
| Retries | retries={N} | Retry up to N times after failure. Each attempt is recorded. |
| Timeout | timeoutMs={N} | Fail the attempt after N milliseconds. Combines with retries. |
| Continue on fail | continueOnFail | Let subsequent tasks run even if this task fails. |
| Skip | skipIf={boolean} | Skip the task at render time. Evaluated once per render cycle. |
| Branch | <Branch if={...} then={...} else={...} /> | Route to different tasks based on a condition. |
| Conditional rendering | {condition ? <Task /> : null} | Mount tasks only when prerequisites are available. |
Next Steps
- Resumability — How failed runs can be resumed after fixing issues.
- Debugging — Inspect failed attempts and error details.
- Execution Model — How retries and node states work internally.