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: claude → copilot → codex. 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.
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. Afallback-engineslist 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
Resolution order:
claude→copilot→codex. The first engine that succeeds wins; failures are logged but do not surface as job failures until all options are exhausted.Behaviour spec
fallback-enginesomittedWhy this matters
Implementation notes
The
ResolvedEngineTargetchain already lives inpkg/workflow/engine_definition.go. Afallback-enginesfield on the workflow spec could be parsed alongsideengineand compiled into a retry loop at the runner level rather than re-generating the full workflow YAML per fallback. The log-parsing fallback path inpkg/cli/logs_parsing_engines.goand the existing engine resolution fallback (runtime-ID prefix match) show patterns that could be adapted.Alternatives considered