unslothai/unsloth · error · CodexAuthError
ChatGPT returned an invalid token lifetime.
Error message
ChatGPT returned an invalid token lifetime.
What it means
Validation in _validate_token_payload for the token lifetime: expires_in (default 3600) must be int()-coercible — a TypeError/ValueError from int(expires_in) (e.g. a string like 'one_hour', None, or a nested object) is converted into CodexAuthError('ChatGPT returned an invalid token lifetime.'). Valid values are then clamped to [60, 30 days] before computing expires_at.
Source
Thrown at studio/backend/core/inference/openai_codex_auth.py:220
if not isinstance(account_id, str) or not account_id or len(account_id) > 512:
raise CodexAuthError("The ChatGPT account identifier was missing.")
return account_id
def _validate_token_payload(body: Any, previous_refresh_token: str = "") -> dict[str, Any]:
if not isinstance(body, dict):
raise CodexAuthError("ChatGPT returned an invalid token response.")
access_token = body.get("access_token")
refresh_token = body.get("refresh_token") or previous_refresh_token
expires_in = body.get("expires_in", 3600)
if not isinstance(access_token, str) or not access_token:
raise CodexAuthError("ChatGPT returned an invalid token response.")
if not isinstance(refresh_token, str) or not refresh_token:
raise CodexAuthError("ChatGPT did not return a refresh token.")
try:
expires_in = max(60, min(int(expires_in), 30 * 24 * 3600))
except (TypeError, ValueError) as exc:
raise CodexAuthError("ChatGPT returned an invalid token lifetime.") from exc
return {
"access_token": access_token,
"refresh_token": refresh_token,
"expires_at": int(time.time()) + expires_in,
"account_id": extract_chatgpt_account_id(access_token),
}
def save_oauth_bundle(provider_id: str, bundle: dict[str, Any]) -> None:
credential_secrets.upsert_secret(
credential_secrets.OPENAI_CODEX_OAUTH_KIND,
provider_id,
json.dumps(bundle, separators = (",", ":")),
)
def load_oauth_bundle(provider_id: str) -> dict[str, Any] | None:
raw = credential_secrets.get_secret(credential_secrets.OPENAI_CODEX_OAUTH_KIND, provider_id)View on GitHub (pinned to 203007d190)
Solutions
- Retry the token request once — intermittent malformed bodies from intermediaries happen.
- If reproducible, log the raw expires_in value's type to confirm upstream drift, then update the coercion (e.g. accept dict['seconds'] or numeric strings) in _validate_token_payload.
- Ensure mocks/tests send expires_in as an integer.
Defensive patterns
Strategy: validation
Validate before calling
try:
int(body.get('expires_in', 3600))
except (TypeError, ValueError):
raise ValueError('expires_in must be integer-coercible') Try / catch
try:
bundle = _validate_token_payload(body)
except CodexAuthError as e:
if 'token lifetime' in str(e):
body = {**body, 'expires_in': 3600} # sane default; log upstream drift
bundle = _validate_token_payload(body)
else:
raise Prevention
- Treat malformed expires_in as upstream drift: log it and consider a default lifetime rather than failing the whole auth.
- Send integers for expires_in in all mocks/tests.
- Monitor token-endpoint response shapes to catch schema changes early.
When it happens
Trigger: Token endpoint returning expires_in as a non-numeric string, null-extended JSON where it arrives as None (caught by int(None) -> TypeError), or an object like {'seconds': 3600} (int() raises TypeError).
Common situations: Upstream schema change stringifying durations; intermediaries rewriting numeric fields; mocked responses using wrong types.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ChatGPT returned an invalid token response.
- ChatGPT credential update is busy. Please retry.
- ChatGPT returned an invalid access token.
- The ChatGPT account identifier was missing.
- ChatGPT did not return a refresh token.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/a85c91bee2cc786e.
Report an issue: GitHub.