fix(proxy): fail over dead account proxy routes before upstream dispatch - #1542
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 44bc1cc738
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
I picked up the remaining review fixes. Follow-up PR #1546 targets this PR's feature branch and addresses both unresolved P1s:
Commit: Please merge #1546 into Update: GitHub CI is now fully green (CI Required and every applicable job passed). #1546 is MERGEABLE/CLEAN with no review findings or unresolved threads, so it is ready to merge into this feature branch. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
? |
|
I rebased the full three-commit PR series onto current Because my account does not have write permission to
Maintainer handoff: git fetch https://github.com/mereyabdenbekuly-ctrl/codex-lb.git codex/pr-1542-review-fixes
git switch fix/dead-account-proxy-route-failover
git reset --hard FETCH_HEAD
git push --force-with-lease origin fix/dead-account-proxy-route-failoverValidation on the rebased HEAD: 1,795 affected unit/integration tests passed; Ruff check/format, proxy architecture checks, |
|
Both remaining P1 review threads are already marked outdated and are addressed by the settlement/ownership changes in the rebased |
5a410f5 to
542905c
Compare
|
Adopted @mereyabdenbekuly-ctrl's fork rebase ( Topped up over today's merges on
The two outdated review threads on Tests: |
542905c to
4750bd7
Compare
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4750bd7190
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| can_try_other_account = ( | ||
| not require_preferred_account | ||
| and account.id != file_preferred_account_id | ||
| and attempt < max_attempts - 1 | ||
| ) |
There was a problem hiding this comment.
Allow verified fresh replays past dead owner routes
When the first HTTP/SSE stream attempt for a locally verified full-resend continuation hits a confirmed pre-dispatch proxy connect failure, this check runs while require_preferred_account is still true, so the branch raises and returns the dead owner's sanitized 502 instead of using _move_verified_fresh_replay_from_owner to strip the owner anchor and select a healthy account. The same verified replay is already allowed for refresh/post-refresh failures, and without it a safe full-resend previous_response_id request remains pinned to an account whose proxy never dispatched any bytes; run the verified-owner replay step (with the same file/turn-state/single-account guards used below) before deciding this is hard ownership.
AGENTS.md reference: AGENTS.md:L105-L108
Useful? React with 👍 / 👎.
|
Confirmed — the confirmed pre-dispatch branch in app/modules/proxy/_service/streaming/retry.py raises under |
4750bd7 to
a265419
Compare
An account-bound upstream proxy can stop accepting connections while the account stays administratively active. Movable Responses requests selected onto that account then failed with a terminal sanitized 502 (or a bridge startup error) instead of failing over, and client retries could select the same dead route again (#1314). Rebuilt from PR #1322 onto current main, which already carries the sanitized pre-dispatch provenance (`retryable_same_contract` + `failure_phase == "connect"`) this change originally introduced as a dispatch-state enum: - `is_confirmed_pre_dispatch_transport_error` is the single predicate that authorizes cross-account replay; host-wide network loss keeps its account-neutral process recovery path and TLS verification failures stay non-replayable. - A confirmed pre-dispatch connect failure may try the next endpoint in the same resolved proxy pool even for a non-idempotent POST. - Raw HTTP/SSE streaming, native Responses WebSocket connects, and HTTP bridge session startup release the failed account's stream lease, record the bounded transient backoff floor (`record_error_backoff`, shared `ERROR_BACKOFF_THRESHOLD`), exclude the account, and retry another eligible account within the existing attempt and deadline budgets. - Hard previous-response/turn-state/file/single-account ownership fails closed on the original sanitized failure without crossing accounts, and selection exhaustion preserves that failure instead of generating `no_accounts`. - The API-key reservation stays request-scoped and singular across internal failover; ambiguous POST dispatch outcomes are surfaced without replay. Fixes #1314 Supersedes #1322 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lover Maintainer follow-up to the #1322 takeover: pin the negative boundaries of the confirmed pre-dispatch predicate at the externally observable surfaces. - TLS verification connect failures do not authorize same-pool POST fallback or cross-account websocket replay. - Host-wide network loss (proxy_network_unavailable) and post-dispatch body-read failures never classify as confirmed pre-dispatch. - An idle bridge disconnect does not exclude the account or record the transient backoff floor, so healthy accounts stay healthy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…re-dispatch hard-ownership raise A confirmed pre-dispatch connect failure guarantees zero upstream bytes, so the confirmed dead-route branch can safely run the verified-owner replay step (same file/turn-state/single-account guards as the post-refresh path) ahead of the require_preferred_account fail-closed raise, moving a locally verified full-resend to a fresh account instead of erroring. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a265419 to
5bf458d
Compare
Summary
Fix account-bound proxy connection failures that occur before upstream dispatch so movable Responses requests fail over transparently instead of repeatedly selecting the dead route. Ambiguous POST failures and hard account ownership stay fail-closed.
Supersedes #1322 — original implementation by @luawl, taken over per the maintainer notice on that PR. The original commit is preserved with @luawl's authorship, rebuilt onto current
main: since #1322 was opened,mainindependently adopted the sanitized dispatch-provenance layer (retryable_same_contract+failure_phase == "connect"viais_pre_dispatch_connection_failure), so this rework reuses that single source of truth instead of the PR's originaldispatch_stateenum, and reimplements the failover semantics against the current selection/bridge architecture (#1395/#1476/#1492/#1499-era).Fixes #1314
Changes
is_confirmed_pre_dispatch_transport_erroras the single predicate authorizing cross-account replay: proven pre-dispatch connect provenance only, explicitly excluding host-wide network loss (proxy_network_unavailable, which keeps its account-neutral process recovery path) and TLS verification failures._HTTPBridgePreDispatchFailover), bounded by the existing attempt limits, request deadlines, and a monotonic exclusion set.record_error_backoff, sharedERROR_BACKOFF_THRESHOLD: 30s floor, 300s cap) so independent requests stop rediscovering the dead route one generic error at a time. No pause/deactivation/rate-limit/quota penalty.no_accounts), and fail closed on it for previous-response, turn-state, uploaded-file, and required-account contracts. The request-scoped API-key reservation stays singular across internal failover and settles exactly once.connect_responses_websocket(previously collapsed to the process-network case only).Diff composition
openspec/changes/retry-account-proxy-connect-failures/(174 additions), strict validation passesTest plan
The new streaming (3) and bridge (3) regressions were verified to fail against unpatched
main(dead route surfaced terminally / bridge startup raised to the client) and pass with this change.🤖 Generated with Claude Code