Repository navigation
fix(opencode): carry the provider's HTTP status on a failed turn (429 pauses instead of retrying) - #264
Merged
Conversation
…a 429 pauses in agent-runtime instead of retrying
tangletools
approved these changes
Oct 18, 2026
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved PR — f1be90b6
Blanket team auto-approval is intentional. This is not a code review.
No automated review runs on this PR. This approval rests on the rule above alone.
tangletools · auto-approval · reason: blanket_auto_approve · 2026-10-18T23:56:49Z
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem. opencode reports a provider refusal as an APIError,
{ name: 'APIError', data: { message, statusCode, isRetryable } }. The opencode backend kept onlydata.message. A 429 therefore reached agent-runtime as bare prose, e.g.bridgeExecutor: bridge stream error: opencode: Rate limit reached for requestsor... opencode: Usage limit reached. Runtime reads a status field, never prose (src/runtime/supervise/upstream-unavailable.ts), so it classed the errortransientand retried after about 4.5 s instead of pausing. Measured on discovery-lab run magnetar-rust-20261017c: 636 driver attempts ended this way (569 usage-limit, 67 rate-limit), each withclassification: transientand aretryInMsof a few seconds. The Lab scorecard counts each one as 'a 429 killed the turn'.Change.
src/backends/opencode.tsbuilds aBackendFailureReasonand carriesdata.statusCodeasstatuswhen it is an integer HTTP status. It never infers a status from prose, the same rulecodexFailureReasonfollows. The end-of-process path yields the terminal error delta instead of throwing, as codex does, so the status reaches the caller there too. agent-runtime'sbridgeUpstreamErroralready readserror.status; a 429 maps tohttp-429, thenunavailable, then a recordedpausedrow (15 s, doubling to 300 s) that spends no attempt.Tests.
tests/opencode-error-message.test.tsis deleted, not updated: it is a mock-spawner test that asserted the thrown error, and test policy deletes a mock test that breaks on a valid API change. The proof is live: the next Discovery free-seat canary must record 0 driver attempts ended by a rate or usage limit, against 636 on magnetar-rust-20261017c.Deploy. discovery-lab's bridges (disco-bridge@8899/8900/8901) run detached checkouts at
ebd7466. op-research ordered the rollout one bridge at a time, after the running RSS proof's verdict.Run ID: run_c626287e8a8ebbf7f143ad22de478074