You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TransportError::RetryLimit is defined and matched throughout the codebase (in api_bridge.rs it becomes CodexErr::RetryLimit → ResponseTooManyFailedAttempts), but it can never actually be emitted by run_with_retry.
The loop is for attempt in 0..=policy.max_attempts (inclusive upper bound). On the final iteration where attempt == max_attempts, should_retry returns false (its own guard: if attempt >= max_attempts { return false; }), so the match falls to Err(err) => return Err(err) — returning the raw underlying error. The Err(TransportError::RetryLimit) after the loop is dead code; the loop always exits via an early return before reaching it.
Impact: After exhausting all retries, callers receive a raw Http 5xx or TransportError::Network instead of TransportError::RetryLimit. The match arm for RetryLimit in api_bridge.rs (line 122) is therefore also dead. Users never see the ResponseTooManyFailedAttempts error the system was designed to surface.
What steps can reproduce the bug?
This is a code-reading bug — no runtime reproduction needed. Read codex-rs/codex-client/src/retry.rs:
run_with_retry loops for attempt in 0..=policy.max_attempts
On the last iteration (attempt == max_attempts), should_retry returns false
The Err(err) => return Err(err) branch fires, returning the raw error
Err(TransportError::RetryLimit) at line 72 is never reached
Proposed fix (one character): Change 0..=policy.max_attempts to 0..policy.max_attempts
// Beforefor attempt in0..=policy.max_attempts{// After for attempt in0..policy.max_attempts{
This makes the loop run exactly max_attempts times, and when exhausted, falls through to Err(TransportError::RetryLimit) as intended.
What is the expected behavior?
After exhausting all retries, run_with_retry should return Err(TransportError::RetryLimit). This would then be correctly converted by api_bridge.rs into CodexErr::RetryLimit → ResponseTooManyFailedAttempts, giving users a clear, actionable error message instead of a raw 5xx or network error.
Additional information
The fix is a single character change — ..= to .. on the for loop range in run_with_retry. No other files need to change. The existing RetryLimit handling in api_bridge.rs and protocol/src/error.rs is already correct and will work properly once this is fixed.
Activity