anomalyco / anomalyco/opencode
Transient provider-busy 503 kills the turn with no retry - headless/ACP sessions wedge idle indefinitely
@jlongster is already working on this.
Since Sep 6, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
When an OpenAI-compatible provider returns a transient 503 ("no eligible device" / model temporarily unavailable), opencode does not retry: the error kills the in-flight turn. In autonomous/headless operation (e.g. as a gascity ACP harness) there is no human to re-prompt, so the session sits idle indefinitely with its work item stuck in_progress. Fast-fail is reasonable for interactive throughput, but it is broken for liveness in unattended loops.
Environment
- opencode 1.18.29 (ACP, subprocess provider)
- Provider: self-hosted OpenAI-compatible endpoint with bounded concurrency (returns 503 immediately when all inference slots are busy, rather than queueing)
Repro
- Run opencode headless as a long-lived agent harness against a provider whose capacity is lower than the number of concurrent consumers.
- Two consumers hold the slots; a third's turn gets an immediate 503 "no eligible device".
- The turn dies. No retry, no backoff, no resume. The session remains listed as active but produces zero activity until an external supervisor kills and respawns it.
- Observed at scale: every lost slot race silently wedges one session; a 12-minute kill+respawn cycle is currently the only retry mechanism. Same wedge reproduced twice on a long-running research session within hours.
Suggestion
Treat provider-busy responses (503 "model unavailable"/"no eligible device", and ideally 429) as retryable within the turn: bounded exponential backoff honoring Retry-After, with a configured attempt budget (default a few minutes of coverage), before surfacing a terminal error. Interactive users can still Ctrl-C; headless loops survive transient capacity contention.
Related: #44044 (managed gateway 503s killing turns) is the same failure class on a different provider path; this report isolates the retry-semantics gap with a minimal self-hosted repro.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.