Skip to content

Feature: fallback engines for resilient agentic workflow execution #48348

Description

@theletterf

Summary

Today each workflow is compiled against exactly one engine (engine: claude, engine: copilot, etc.). If that engine is unavailable — quota exhausted, service outage, auth failure — the entire job fails with no recovery path. A fallback-engines list would let users declare an ordered preference and have gh-aw automatically retry with the next engine when the primary one cannot run.

Proposed syntax

engine: claude
fallback-engines:
  - copilot
  - codex

Resolution order: claudecopilotcodex. The first engine that succeeds wins; failures are logged but do not surface as job failures until all options are exhausted.

Behaviour spec

Scenario Behaviour
Primary engine succeeds No fallback triggered
Primary fails with transient error (rate limit, 5xx) Try next engine in list
Primary fails with config/auth error Try next engine in list
All engines exhausted Job fails with aggregated error messages
fallback-engines omitted No change from today

Why this matters

  • Multi-tenant runners commonly have uneven quota across providers; a fallback avoids hard stops.
  • Copilot BYOK setups may have primary keys scoped to one provider; a cheaper fallback engine can handle overflow.
  • Scheduled / unattended workflows (no human to re-trigger) benefit most — they need resilience baked in.

Implementation notes

The ResolvedEngineTarget chain already lives in pkg/workflow/engine_definition.go. A fallback-engines field on the workflow spec could be parsed alongside engine and compiled into a retry loop at the runner level rather than re-generating the full workflow YAML per fallback. The log-parsing fallback path in pkg/cli/logs_parsing_engines.go and the existing engine resolution fallback (runtime-ID prefix match) show patterns that could be adapted.

Alternatives considered

  • User-side retry workflow: callers can wrap the workflow in a retry loop, but this duplicates boilerplate across every workflow and doesn't capture transient errors that surface inside the compiled YAML.
  • Single engine with model fallback: each engine already supports env-var model fallback, but that doesn't help when the whole provider is down.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions