RetryableError
Expression nodes in workflows can throw RetryableError to signal that the current execution failed due to a transient issue and should be retried automatically by the workflow engine.
Usage
When the workflow engine encounters a RetryableError, it marks the node for retry instead of failing it permanently. The node is re-executed after a delay, following an exponential backoff strategy.
Retry Behavior
| Property | Value |
|---|---|
| Maximum attempts | 9 retries |
| Backoff strategy | Exponential — 30s × 2^(n-1), capped at 5 minutes |
| Total retry window | ~32.5 minutes |
Delay Progression
| Retry | Delay |
|---|---|
| 1 | 30 seconds |
| 2 | 1 minute |
| 3 | 2 minutes |
| 4 | 4 minutes |
| 5 | 5 minutes (cap) |
| 6 | 5 minutes |
| 7 | 5 minutes |
| 8 | 5 minutes |
| 9 | 5 minutes |
When to Use
RetryableError is intended for transient failures — situations where retrying the same operation is likely to succeed:
- External API is temporarily unavailable
- Rate limit hit on a third-party service
- Temporary network issue
- Upstream service returning 503/429
const res = await http.get("https://api.example.com/data");
if (res.status === 429) {
throw RetryableError("Rate limited by external API");
}
if (res.status === 503) {
throw RetryableError("External service unavailable");
}
return res.data;
Don't use RetryableError for permanent failures
If the error is due to bad input, missing configuration, or a logic error, retrying won't help. Let the node fail normally so the issue is surfaced immediately.
What Happens After Max Retries
If all 9 retry attempts are exhausted:
- The node is marked as errored with the last error message
- All child nodes downstream are marked as skipped
- If no other nodes are running, the workflow terminates with an error