تخطَّ إلى المحتوى

Handling Errors

هذا المحتوى غير متوفر بلغتك بعد.

Canonical Error Envelope

Structured application errors use this envelope. Framework validation can instead return a detail array, SlowAPI can return a string-valued error, and intermediary errors may not be JSON. Check value types and HTTP status. The example below must not trigger an automatic retry:

{
"error": {
"code": "NO_HEALTHY_SESSION",
"message": "No healthy upstream session available.",
"type": "account_error",
"request_id": "req_abc123",
"retryable": false
}
}

Some errors (particularly validation and routing errors) may be wrapped in a detail field: {"detail": {"error": {...}}}. Always check for error at both the top level and under detail.

Error codes may arrive in UPPER_SNAKE_CASE or lowercase_snake_case. Always compare case-insensitively.

retryable may be true, false, or null (when retry semantics don’t apply). Treat null as false for safety.

FieldDescription
codeMachine-readable error code (compare case-insensitively)
messageHuman-readable error description
typeError classification
request_idCorrelation ID — also in X-Request-Id response header
retryableWhether the operation is safe to retry (true/false/null)

Retry Strategy

For a request known to be safe to repeat, transient errors can use bounded exponential backoff. retryable: true does not prove a write was not applied. Reconcile run/job status before retrying an uncertain write. The example below is only for callers that have established replay safety; it does not retry network exceptions automatically:

import time
import requests
def retry_request(url, headers, json_body, max_retries=4):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=json_body, timeout=60)
if 200 <= response.status_code < 300:
return response
try:
payload = response.json()
except ValueError:
return response
detail = payload.get("detail") if isinstance(payload, dict) else None
error = payload.get("error") if isinstance(payload, dict) else None
if not isinstance(error, dict) and isinstance(detail, dict):
error = detail.get("error", detail)
if isinstance(error, dict) and error.get("retryable") is True:
wait = min(2 ** attempt, 60) # 1s, 2s, 4s, 8s, max 60s
time.sleep(wait)
continue
return response # Non-retryable error
return response

Non-Retryable Errors

Do not retry these errors — fix the root cause instead:

StatusCodeAction
401INVALID_API_KEYCheck your API key
401MISSING_API_KEYAdd Authorization: Bearer gmk_live_...
401EXPIRED_API_KEYCreate a new key
401REVOKED_API_KEYCreate a new key
403ACCOUNT_REAUTH_REQUIREDReconnect the ChatGPT account in the User App
403CONVERSATION_ACCESS_DENIEDUse the correct API key
403ASSET_ACCESS_DENIEDCheck conversation ownership
400UNSUPPORTED_PARAMETERRemove the unsupported parameter (tools, n>1, etc.)
404CONVERSATION_NOT_FOUNDVerify the conversation ID
404PROJECT_NOT_FOUNDVerify the project ID
404ASSET_NOT_FOUNDVerify the asset ID
413FILE_TOO_LARGEUse a smaller file (max 10 MB)

Note: Error codes may arrive in lowercase (e.g., conversation_not_found). Always compare case-insensitively.

Streaming Errors

During streaming, errors are emitted as structured response.failed lifecycle events — not as assistant content text. See Streaming for the full SSE error contract.

# Python streaming error handling
import json
import httpx
with httpx.stream("POST", url, headers=headers, json=body) as resp:
for line in resp.iter_lines():
if not line.startswith("data: "):
continue
data = line[6:]
if data == "[DONE]":
break
chunk = json.loads(data)
lifecycle = chunk.get("lifecycle_event")
if lifecycle and lifecycle["type"] == "response.failed":
err = lifecycle["error"]
print(f"Error: {err['code']} — {err['message']}")
if err.get("retryable"):
# Retry with backoff
pass
break # Stop processing
content = chunk["choices"][0]["delta"].get("content", "")
print(content, end="")

Request ID

Every response includes an X-Request-Id header. If you send an X-Request-Id header in your request, it is echoed back. Always include this ID when reporting issues to support.

Next Steps