From d63e44ae290ad449869add2e7492adfaf687bb48 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 25 Aug 2025 19:18:16 -0700 Subject: [PATCH] Fixed a bug that causes token refresh to not work in a seamless manner (#2699) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR fixes a bug in the token refresh logic. Token refresh is performed in a retry loop so if we receive a 401 error, we refresh the token, then we go around the loop again and reissue the fetch with a fresh token. The bug is that we're not using the updated token on the second and subsequent times through the loop. The result is that we'll try to refresh the token a few more times until we hit the retry limit (default of 4). The 401 error is then passed back up to the caller. Subsequent calls will use the refreshed token, so the problem clears itself up. The fix is straightforward — make sure we use the updated auth information each time through the retry loop. --- codex-rs/core/src/client.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index ecf1ae71..b5f8e4dc 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -142,9 +142,12 @@ impl ModelClient { } let auth_manager = self.auth_manager.clone(); - let auth = auth_manager.as_ref().and_then(|m| m.auth()); - let auth_mode = auth.as_ref().map(|a| a.mode); + let auth_mode = auth_manager + .as_ref() + .and_then(|m| m.auth()) + .as_ref() + .map(|a| a.mode); let store = prompt.store && auth_mode != Some(AuthMode::ChatGPT); @@ -211,15 +214,18 @@ impl ModelClient { let mut attempt = 0; let max_retries = self.provider.request_max_retries(); - trace!( - "POST to {}: {}", - self.provider.get_full_url(&auth), - serde_json::to_string(&payload)? - ); - loop { attempt += 1; + // Always fetch the latest auth in case a prior attempt refreshed the token. + let auth = auth_manager.as_ref().and_then(|m| m.auth()); + + trace!( + "POST to {}: {}", + self.provider.get_full_url(&auth), + serde_json::to_string(&payload)? + ); + let mut req_builder = self .provider .create_request_builder(&self.client, &auth)