Skip to content

fix(opencode): carry the provider's HTTP status on a failed turn (429 pauses instead of retrying) - #264

Merged
drewstone merged 1 commit into
mainfrom
fix/opencode-provider-status
Oct 18, 2026
Merged

drewstone merged 1 commit into
mainfrom
fix/opencode-provider-status

Conversation

@drewstone

Copy link
Copy Markdown
Owner

Problem. opencode reports a provider refusal as an APIError, { name: 'APIError', data: { message, statusCode, isRetryable } }. The opencode backend kept only data.message. A 429 therefore reached agent-runtime as bare prose, e.g. bridgeExecutor: bridge stream error: opencode: Rate limit reached for requests or ... opencode: Usage limit reached. Runtime reads a status field, never prose (src/runtime/supervise/upstream-unavailable.ts), so it classed the error transient and 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 with classification: transient and a retryInMs of a few seconds. The Lab scorecard counts each one as 'a 429 killed the turn'.

Change. src/backends/opencode.ts builds a BackendFailureReason and carries data.statusCode as status when it is an integer HTTP status. It never infers a status from prose, the same rule codexFailureReason follows. 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's bridgeUpstreamError already reads error.status; a 429 maps to http-429, then unavailable, then a recorded paused row (15 s, doubling to 300 s) that spends no attempt.

Tests. tests/opencode-error-message.test.ts is 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

…a 429 pauses in agent-runtime instead of retrying

@tangletools tangletools left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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

@drewstone
drewstone merged commit c7497ad into main Oct 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants