Workflow limits, statuses, and error codes

Use this reference when validating a Workflow graph, interpreting Audit, or deciding whether a failure can retry. These are FastHook-owned limits from the current Workflow API and worker contracts. A connected provider can impose additional quotas, payload limits, scopes, and rate limits.

Workflow graph limits

| Resource | Current limit | | --- | ---: | | Workflow name | 155 characters | | Workflow description | 4,000 characters | | Steps per Workflow | 100 | | Edges per Workflow | 250 | | Step name | 155 characters | | Action configuration | 64 KiB | | Action invocation inputs | 64 KiB | | Step configuration | 64 KiB | | Edge mapping and condition | 64 KiB each | | Paths in one Paths Step | 2–10 | | Path name | 80 characters | | Branch or legacy Path expression | 4,000 characters | | Fallback Paths in one Paths Step | 1 | | Error routes from one Step | 1 | | Delay | 1 second–30 days |

The graph must be acyclic. Every Step must be reachable through an incoming Edge from the Trigger or another Step. A Step cannot connect to itself, and duplicate routes are rejected.

The 64 KiB checks apply to the JSON-serialized value. Large provider payloads belong in runtime data, not in saved Step configuration.

API and Audit limits

| Operation | Default | Maximum | | --- | ---: | ---: | | List Workflows | 100 | 255 | | List Workflow runs | 100 | 255 | | Search Workflow activity | 100 | 100 | | Activity search query | — | 200 characters |

Audit can return redacted previews when include_data=true. A stored object larger than 64 KiB is reported as available but does not receive an inline preview. Within a preview, strings are truncated after 8,000 characters and arrays or objects after 100 items or fields. Keys that look like credentials, secrets, signatures, cookies, or tokens are redacted.

Preview limits do not change the stored runtime object. They only bound what the control API returns for inspection.

Workflow statuses

| Status | Meaning | | --- | --- | | draft | Editable and not eligible to start new runs. | | active | Eligible to start a run for each new event from its Source. | | paused | Temporarily stops new runs without deleting the Workflow definition. | | disabled | Inactive and retained for later inspection or reconfiguration. |

Saving a graph increments the Workflow version. Existing run evidence remains associated with the version that executed.

Run and Step statuses

Workflow runs use four statuses:

Individual Step records use pending, running, succeeded, failed, or skipped. A skipped Step did not execute—for example, its Path was not selected or an earlier terminal failure made it unreachable. It is not a provider failure by itself.

Direct webhook Events retain their existing uppercase status model: SCHEDULED, QUEUED, HOLD, SUCCESSFUL, FAILED, and CANCELLED. See Retries and replay for webhook delivery behavior and Runs and errors for Workflow execution.

Retry behavior

An Action is retryable when the provider executor returns HTTP 429, an HTTP 5xx response, or an explicit retryable: true result. An unavailable Action executor is also treated as temporary.

FastHook does not assume that an Action is safe to repeat. Use provider idempotency keys where available and design externally visible side effects to tolerate duplicate attempts.

After queue retries are exhausted, the run and any pending or running Step records become failed with workflow_delivery_exhausted.

Normalized error route data

An error route receives a public envelope instead of successful Step output:

JSON
{
  "code": "ACTION_EXECUTION_FAILED",
  "message": "Action returned HTTP 429",
  "step_id": "wfs_example",
  "step_name": "Send message",
  "provider": "slack",
  "attempt": 2,
  "status": 429,
  "retryable": true,
  "details": {}
}

status can be null when no HTTP response exists. provider can also be null for non-provider Steps. Treat details as provider- or runtime-specific data and avoid building core routing logic around undocumented fields inside it.

Public error codes

| Code | Produced by | | --- | --- | | ACTION_EXECUTION_FAILED | Action Step | | TRANSFORMATION_EXECUTION_FAILED | JSON Patch or reusable transformation Step | | BRANCH_EVALUATION_FAILED | Paths or branch evaluation | | STEP_EXECUTION_FAILED | Destination, Filter, Delay, or another executable Step kind |

Audit also preserves a more specific internal failure code for diagnosis. Common examples include action_executor_unavailable, action_http_429, workflow_mapping_required_fields_missing, workflow_json_patch_failed, workflow_transformation_failed, workflow_filter_invalid, workflow_delay_invalid, and workflow_delivery_exhausted. The normalized public code is stable for routing by Step kind; use the specific Audit code when troubleshooting the root cause.

HTTP API status codes

| HTTP status | Meaning | | ---: | --- | | 400 | Malformed input, invalid filter, or unsupported status value. | | 401 | Missing or invalid authentication. | | 403 | The credential cannot access the requested team or resource. | | 404 | The Workflow, run, Source, or referenced resource does not exist in scope. | | 409 | A Workflow update used a stale version or otherwise conflicts with current state. | | 422 | The graph, mapping, configuration, or provider input failed semantic validation. | | 429 | A platform or provider rate limit was reached; inspect retry information. | | 5xx | A temporary platform, executor, or provider failure may be retryable. |

For request and response schemas, use the API Reference or the machine-readable OpenAPI document. For recovery design, continue with Workflow error handling.