Skip to main content
Workflow errors are error types you can throw within your workflow and step functions to control execution flow and retry behavior. These errors give you fine-grained control over how failures are handled.

FatalError

A fatal error stops retries immediately and fails the step. Use this when you encounter a permanent failure condition that won’t succeed on retry.

When to Use FatalError

  • Resource not found - API returns 404
  • Invalid input - Validation failures
  • Permission denied - Authentication/authorization errors (401, 403)
  • Business logic violations - Insufficient funds, duplicate orders
  • Configuration errors - Missing required environment variables

Basic Usage

API Reference

Parameters:
  • message (string) - Error message describing the failure
Properties:
  • name - Always "FatalError"
  • message - The error message
  • fatal - Always true
  • stack - Stack trace
Methods:
  • FatalError.is(value) - Type guard to check if value is a FatalError

Examples

RetryableError

A retryable error allows you to customize when a step should be retried. Use this when you know how long to wait before the operation might succeed.

When to Use RetryableError

  • Rate limiting - API returns 429 with Retry-After header
  • Temporary unavailability - Service is temporarily down (503)
  • Backpressure - System is overloaded but will recover
  • Exponential backoff - Progressive retry delays
  • Scheduled retries - Retry at a specific time

Basic Usage

API Reference

Parameters:
  • message (string) - Error message describing the failure
  • options (object, optional) - Retry configuration
    • retryAfter (number | string | Date, optional) - When to retry
      • Number: milliseconds
      • String: duration (e.g., "5s", "2m", "1h")
      • Date: specific time to retry
      • Default: 1 second (1000ms)
Properties:
  • name - Always "RetryableError"
  • message - The error message
  • retryAfter - Date when the step should be retried
  • stack - Stack trace
Methods:
  • RetryableError.is(value) - Type guard to check if value is a RetryableError

Examples

Combining FatalError and RetryableError

Use both error types together to handle different failure scenarios appropriately:

Best Practices

  1. Use FatalError for permanent failures
    • Don’t waste retries on errors that will never succeed
    • Examples: validation errors, 404s, permission errors
  2. Use RetryableError for temporary failures
    • Respect rate limits and backpressure signals
    • Use appropriate delays based on the error type
  3. Set appropriate maxRetries
  4. Implement exponential backoff
    • Use getStepMetadata() to access attempt number
    • Increase delay with each attempt
  5. Make steps idempotent
    • Steps may execute multiple times
    • Ensure repeated execution is safe
    • See Idempotency Guide
  6. Include helpful error messages