Errors
Handle GLM 5 API validation, authentication, quota, and server errors.
Non-streaming errors use an OpenAI-compatible object:
{
"error": {
"message": "Invalid API key provided.",
"type": "invalid_request_error",
"code": "invalid_api_key",
"param": null
}
}This is the same shape most OpenAI and OpenRouter-compatible SDKs expect:
inspect error.code for application logic and the HTTP status for retry
decisions.
Error reference
| HTTP | Code | Meaning | Retry? |
|---|---|---|---|
| 400 | invalid_request_error | Malformed JSON, messages, tool arguments, or tool-result sequence. | No |
| 400 | context_length_exceeded | The upstream model rejected the request because it exceeds its context window. | No |
| 400 | unsupported_parameter | The selected model does not support the requested feature. | No |
| 401 | invalid_api_key | The bearer key is missing, invalid, disabled, or deleted. | No |
| 402 | insufficient_quota | The credit balance cannot cover the reservation. | No |
| 404 | model_not_found | The model ID is not in the public model list. | No |
| 413 | request_too_large | The request body exceeds 4 MB. | No |
| 429 | rate_limit_exceeded | The API key exceeded its requests-per-minute limit. | Yes |
| 500 | internal_error | An unexpected server or provider error occurred. | Yes |
| 503 | service_unavailable | Public API access is temporarily unavailable. | Yes |
Retry policy
Retry only temporary failures:
429: respect backoff and reduce concurrency.500: retry with exponential backoff.503: retry later.
Do not automatically retry 400, 401, 402, 404, or 413. Fix the
request, credentials, balance, or model selection first.
For context_length_exceeded, remove or summarize older messages, reduce tool
definitions, or lower max_completion_tokens. This limit comes from the
selected upstream model rather than a GLM 5 application-level token cap. Failed
requests are reconciled so the reservation is refunded.
async function withBackoff<T>(operation: () => Promise<T>): Promise<T> {
let delay = 500;
for (let attempt = 0; attempt < 4; attempt += 1) {
try {
return await operation();
} catch (error: any) {
const status = error?.status;
if (![429, 500, 503].includes(status) || attempt === 3) {
throw error;
}
await new Promise((resolve) => setTimeout(resolve, delay));
delay *= 2;
}
}
throw new Error('Unreachable');
}Streaming errors
After a streaming response has begun, an error arrives inside the SSE stream:
data: {"error":{"message":"Internal server error.","type":"server_error","code":"internal_error","param":null}}Handle both the initial HTTP status and error objects received during the stream.
Diagnose growing-context failures
If a long-running client starts returning 402 insufficient_quota, inspect:
- The most recent
usage.prompt_tokens. - Whether the client resends all previous messages.
- The requested
max_completion_tokens. - The remaining GLM 5 credit balance.