usestrix/strix · error · CodexAuthError
bad_response
bad_response
Error message
bad_response: token endpoint returned non-object
What it means
CodexAuthError with code `bad_response` raised when the token endpoint returns HTTP 200 but the body is not a JSON object (e.g. a JSON array, string, number, or empty content coerced to `{}`). It means the endpoint answered successfully but the OAuth contract is violated.
Source
Thrown at strix/config/codex.py:237
detail = ""
try:
with requests.post(
TOKEN_URL,
data=payload,
headers={"Accept": "application/json"},
timeout=_TOKEN_TIMEOUT,
) as response:
status_code = response.status_code
body = response.content
if status_code >= 400:
detail = response.text[:300]
except requests.RequestException as exc:
raise CodexAuthError("unavailable", str(exc)) from exc
if status_code >= 400:
raise CodexAuthError("token_http_error", f"HTTP {status_code}: {detail}")
data = json.loads(body or b"{}")
if not isinstance(data, dict):
raise CodexAuthError("bad_response", "token endpoint returned non-object")
return data
def _record_from_token_response(
data: dict[str, Any], refresh_fallback: str | None = None
) -> dict[str, Any]:
access = data.get("access_token")
# A refresh response may omit refresh_token when it isn't rotated; keep the old one.
refresh = data.get("refresh_token") or refresh_fallback
expires_in = data.get("expires_in")
if not isinstance(access, str) or not access:
raise CodexAuthError("bad_response", "token response missing access_token")
if not isinstance(refresh, str) or not refresh:
raise CodexAuthError("bad_response", "token response missing refresh_token")
account_id = _account_id_from_jwt(access) or _account_id_from_jwt(
data.get("id_token") if isinstance(data.get("id_token"), str) else ""
)
if not account_id:View on GitHub (pinned to 8551339130)
Solutions
- Capture the raw body to identify what actually came back (add temporary logging of `body[:300]` before the parse)
- If behind a proxy/VPN, bypass it for auth.openai.com and retry
- If the endpoint contract changed, update to the latest Strix version which tracks the Codex CLI OAuth flow
- Re-login: `strix auth login` after fixing the network path
Defensive patterns
Strategy: retry
Try / catch
from strix.config.codex import CodexAuthError
try:
data = exchange_code(code, verifier)
except CodexAuthError as e:
if e.code == "bad_response" and "non-object" in str(e):
# endpoint/proxy misbehavior — one retry on a clean path, then surface
... Prevention
- Bypass HTTP-intercepting proxies/VPN for auth.openai.com — transparent middleboxes cause 200-with-garbage responses
- Pin to a maintained Strix version so OAuth-contract fixes are picked up
- Retry once on transient bad_response before escalating; persistent recurrence means the network path is broken
When it happens
Trigger: `exchange_code()` or `refresh_tokens()` receives a 200 response whose parsed JSON `isinstance(data, dict)` is False — a misbehaving gateway, HTML error page with 200 status, or API change at auth.openai.com.
Common situations: Captive portals or 'successful' proxy pages returning HTML with status 200; OpenAI changing the token endpoint shape; transparent content-inspection middleboxes mangling responses. Extremely rare in practice.
Related errors
- token_http_error
- unavailable
- no_account_id
- not_authenticated
- Cannot resume scan {scan_id}: agents.json is unreadable: {ex
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/cfe5c94286524bba.
Report an issue: GitHub.