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
Improved token refresh handling to address "Re-connecting" behavior (openai#6231)
Currently, when the access token expires, we attempt to use the refresh
token to acquire a new access token. This works most of the time.
However, there are situations where the refresh token is expired,
exhausted (already used to perform a refresh), or revoked. In those
cases, the current logic treats the error as transient and attempts to
retry it repeatedly.
This PR changes the token refresh logic to differentiate between
permanent and transient errors. It also changes callers to treat the
permanent errors as fatal rather than retrying them. And it provides
better error messages to users so they understand how to address the
problem. These error messages should also help us further understand why
we're seeing examples of refresh token exhaustion.
Here is the error message in the CLI. The same text appears within the
extension.
<img width="863" height="38" alt="image"
src="https://github.com/user-attachments/assets/7ffc0d08-ebf0-4900-b9a9-265064202f4f"
/>
I also correct the spelling of "Re-connecting", which shouldn't have a
hyphen in it.
Testing: I manually tested these code paths by adding temporary code to
programmatically cause my refresh token to be exhausted (by calling the
token refresh endpoint in a tight loop more than 50 times). I then
simulated an access token expiration, which caused the token refresh
logic to be invoked. I confirmed that the updated logic properly handled
the error condition.
Note: We earlier discussed the idea of forcefully logging out the user
at the point where token refresh failed. I made several attempts to do
this, and all of them resulted in a bad UX. It's important to surface
this error to users in a way that explains the problem and tells them
that they need to log in again. We also previously discussed deleting
the auth.json file when this condition is detected. That also creates
problems because it effectively changes the auth status from logged in
to logged out, and this causes odd failures and inconsistent UX. I think
it's therefore better not to delete auth.json in this case. If the user
closes the CLI or VSCE and starts it again, we properly detect that the
access token is expired and the refresh token is "dead", and we force
the user to go through the login flow at that time.
This should address aspects of openai#6191, openai#5679, and openai#5505
@@ -22,10 +24,14 @@ use crate::auth::storage::AuthStorageBackend;
22
24
usecrate::auth::storage::create_auth_storage;
23
25
usecrate::config::Config;
24
26
usecrate::default_client::CodexHttpClient;
27
+
usecrate::error::RefreshTokenFailedError;
28
+
usecrate::error::RefreshTokenFailedReason;
25
29
usecrate::token_data::PlanType;
26
30
usecrate::token_data::TokenData;
27
31
usecrate::token_data::parse_id_token;
28
32
usecrate::util::try_parse_error_message;
33
+
use serde_json::Value;
34
+
use thiserror::Error;
29
35
30
36
#[derive(Debug,Clone)]
31
37
pubstructCodexAuth{
@@ -46,26 +52,63 @@ impl PartialEq for CodexAuth {
46
52
// TODO(pakrym): use token exp field to check for expiration instead
47
53
constTOKEN_REFRESH_INTERVAL:i64 = 8;
48
54
55
+
constREFRESH_TOKEN_EXPIRED_MESSAGE:&str = "Your access token could not be refreshed because your refresh token has expired. Please log out and sign in again.";
56
+
constREFRESH_TOKEN_REUSED_MESSAGE:&str = "Your access token could not be refreshed because your refresh token was already used. Please log out and sign in again.";
57
+
constREFRESH_TOKEN_INVALIDATED_MESSAGE:&str = "Your access token could not be refreshed because your refresh token was revoked. Please log out and sign in again.";
58
+
constREFRESH_TOKEN_UNKNOWN_MESSAGE:&str =
59
+
"Your access token could not be refreshed. Please log out and sign in again.";
0 commit comments