HKUDS/DeepTutor · error · CodexHTTPError
{friendly_error(response.status_code)}
Error message
{friendly_error(response.status_code)} What it means
When the Codex SSE endpoint returns a non-success HTTP status, _request_codex raises CodexHTTPError with a friendly, status-specific message; the raw body (first 500 bytes) is logged at debug level so operators can diagnose without leaking it to users.
Source
Thrown at deeptutor/services/llm/provider_core/openai_codex_provider.py:227
async def _request_codex(
url: str,
headers: dict[str, str],
body: dict[str, Any],
verify: bool,
on_content_delta: Callable[[str], Awaitable[None]] | None = None,
) -> tuple[str, list[ToolCallRequest], str]:
async with httpx.AsyncClient(timeout=60.0, verify=verify) as client:
async with client.stream("POST", url, headers=headers, json=body) as response:
if response.status_code != 200:
raw = await response.aread()
# Kept out of the reply the learner sees, but an operator cannot
# diagnose an upstream rejection without the body.
logger.debug(
"Codex API returned HTTP {}: {}",
response.status_code,
raw.decode("utf-8", "ignore")[:500],
)
raise CodexHTTPError(
response.status_code,
_friendly_error(response.status_code),
)
return await consume_sse(response, on_content_delta)
def _prompt_cache_key(messages: list[dict[str, Any]]) -> str:
raw = json.dumps(messages, ensure_ascii=True, sort_keys=True)
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
def _friendly_error(status_code: int) -> str:
if status_code == 401:
return "Codex login expired. The session was refreshed; retry this request."
if status_code == 403:
return "This Codex account is not allowed to make the requested call."
if status_code == 429:
return "Codex usage quota exceeded or rate limit triggered. Please try again later."View on GitHub (pinned to 3e82f13042)
Solutions
- Match the friendly message to the status: 429 → back off and retry; 401 → re-login; 5xx → retry later.
- Enable debug logging to see the truncated response body.
- Check model name and request size if errors are consistent.
Defensive patterns
Strategy: retry
Try / catch
try:
resp = await provider.chat(messages)
except CodexHTTPError as e:
if e.status_code == 429:
await asyncio.sleep(backoff()); retry()
elif e.status_code >= 500:
retry_later()
else:
raise # 4xx needs user action Prevention
- Map status codes to policies: retry 429/5xx, escalate 401/403/404
- Enable debug logging in staging to capture truncated bodies
- Circuit-break after repeated failures to avoid hammering upstream
When it happens
Trigger: chat/chat_stream → _call_codex → _request_codex receives e.g. 401 (expired token), 429 (rate limit), 5xx (upstream failure).
Common situations: Rate limits during heavy usage; expired session tokens; OpenAI-side incidents; malformed model names producing 404.
Related errors
- Local LLM error: {error_text}
- Local LLM stream error: {error_text}
- Embedding provider returned HTTP {response.status_code}
- OpenAI SDK request failed: {exc}
- OpenAI API error: {error_text}
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/370f9d022a2832c0.
Report an issue: GitHub.