本文档帮助您理解 TokenHub API 的错误响应格式,快速定位并解决调用问题。
一、OpenAI 兼容协议(标准链路)
TokenHub 默认采用 OpenAI 兼容协议。当 API 调用出错时,HTTP 状态码为非 2xx,响应体为 JSON 格式。
1.1 错误响应结构
{"error": {"type": "<错误类型>","code": "<业务错误码>","message": "<错误描述>","source": "client | gateway | upstream","upstream_code": "<上游错误码,仅上游错误时返回>","upstream_status": "<上游 HTTP 状态码,仅上游错误时返回>","request_id": "<请求唯一标识>"}}
字段说明:
字段 | 类型 | 说明 |
type | string | 错误类型,用于程序判断错误大类。 |
code | string | 平台业务错误码(如 401002),用于精确定位问题。部分场景下错误码可能为上游组件传递的字符串。 |
message | string | 可读的错误描述。 |
source | string | 错误来源: client(请求端)、gateway(网关)、upstream(上游服务)。 |
upstream_code | string | 上游服务原始错误码,仅当 source=upstream 时出现。 |
upstream_status | number | 上游服务 HTTP 状态码,仅当 source=upstream 时出现。 |
request_id | string | 请求 ID,用于问题排查和提交工单。 |
1.2 错误类型与 HTTP 状态码对照表
下表基于 maas-gateway 的真实映射整理(errhandler 根据 HTTP 状态码映射
error.type):HTTP 状态码 | 错误类型 Type | 错误码 Code | 错误信息 Message(示例) | 含义 |
400 | invalid_request_error | 400001 400002 400004 | "invalid parameter 'model': model is required" | 请求参数不合法 |
401 | authentication_error | 401002 | "invalid api key" | API Key 无效 / 鉴权失败 |
402 | permission_error | 401007 401008 403004 | "endpoint is inactive: FREE_QUOTA_EXHAUSTED" | 套餐或计费限制 |
403 | permission_error | 403001 403002 403005 | "access denied: client IP ..." | 权限不足 / 白名单限制 |
429 | rate_limit_error | 429001 | "rate limit exceeded on dimension: rpm" | 限流触发 |
451 | content_filter_error | 451001 | "content was filtered by safety policy" | 内容安全拦截 |
502 | upstream_error | 502001 或上游 code | "provider overloaded" | 上游模型服务报错 |
503 | service_unavailable | 503001 | "service unavailable" | 网关 / 依赖服务不可用 |
504 | timeout_error | 504001 | "gateway timeout" | 超时 |
410 | server_error(当前实现) | 410001 | "session 'xxx' has expired ..." | 会话亲和失效 |
499 | server_error(当前实现) | 499001 | "request was canceled" | 客户端主动取消 |
注意:
410/499 在当前实现中会落到 server_error(因为类型映射未单独覆盖这两个状态码),这是“真实返回行为”。
Pre 阶段短路错误(writeChainError)使用固定
type = "gateway_error",不在上表 error.type 映射范围内。1.3 业务错误码速查表
以下为 maas-gateway 定义的全部业务错误码(GatewayError 定义)。
HTTP | 业务码 | message 示例 | 触发场景 |
400 | 400001 (CodeInvalidRequest) | "invalid json ..." / "request body must not be empty" | 请求体不是合法 JSON 或为空 |
400 | 400002 (CodeInvalidParameter) | "invalid parameter 'model': model is required" | 必填字段缺失或字段值非法 |
400 | 400003 (CodeInputTooLong) | "input length 32768 exceeds model limit 8192" | 输入 token 数超出模型上下文窗口 |
400 | 400004 (CodeModelNotFound) | "model 'gpt-9-turbo' not found" | 请求的 model 在平台不存在 |
400 | 400005 (CodeUnsupportedModel) | "model 'hunyuan-lite' does not support protocol 'openai'" | 模型不支持当前请求协议或能力(如 ai_search) |
400 | 400006 (CodeUnsupportedFormat) | "unsupported response format: 'xml'" | 请求的 response_format 或输出格式不被模型支持 |
401 | 401001 (CodeUnauthorized) | "unauthorized" | 未携带任何认证信息,或认证方式无法识别 |
401 | 401002 (CodeInvalidAPIKey) | "invalid api key" | API Key 不存在或签名校验失败 |
401 | 401003 (CodeAPIKeyExpired) | "API key has expired" | API Key 已超过有效期 |
401 | 401004 (CodeAPIKeyDisabled) | "API key is disabled by user" / "api key is blocked" | API Key 被主动禁用或被后台封禁 |
401 | 401005 (CodeSignatureInvalid) | "cam signature verification failed" | CAM / 自定义签名校验不通过 |
400 | 401006 (CodeInvalidEndpoint) | "invalid endpoint or model" | Endpoint 不存在或模型与 Endpoint 不匹配 |
402 | 401007 (CodeEndpointNoFreePackage) | "endpoint is inactive: NO_FREE_PACKAGE" | Endpoint 下无可用免费套餐 |
402 | 401008 (CodeEndpointFreeQuotaExhausted) | "endpoint is inactive: FREE_QUOTA_EXHAUSTED" | Endpoint 免费配额已耗尽 |
403 | 403001 (CodePermissionDenied) | "Plan packet is disabled by user" | 套餐包被禁用,或无调用权限 |
403 | 403002 (CodeModelAccessDenied) | "Model hunyuan-pro is not authorized for this API key" | API Key 未被授权访问该模型 |
403 | 403003 (CodeAccountBlocked) | "account is blocked" | 账号(UIN)被后台封禁 |
402 | 403004 (CodeInsufficientBalance) | "endpoint is inactive: BILLING_ISOLATED" | 账户欠费隔离,计费服务冻结 |
403 | 403005 (CodeIPNotAllowed) | "access denied: client IP 1.2.3.4 is not in the allowlist" | 来源 IP 不在 API Key 白名单内 |
429 | 429001 (CodeRateLimitExceeded) | "rate limit exceeded on dimension: rpm" | 综合限流触发(维度由网关决策) |
429 | 429002 (CodeRPMLimitExceeded) | "rate limit exceeded on dimension: rpm" | 每分钟请求数(RPM)超限(预留,当前由 429001 统一上报) |
429 | 429003 (CodeTPMLimitExceeded) | "rate limit exceeded on dimension: tpm" | 每分钟 token 数(TPM)超限(预留) |
429 | 429004 (CodeTPDLimitExceeded) | "rate limit exceeded on dimension: tpd" | 每日 token 数(TPD)超限(预留) |
429 | 429005 (CodeConcurrencyLimitExceeded) | "rate limit exceeded on dimension: concurrency" | 并发数超限(预留) |
499 | 499001 (CodeRequestCanceled) | "request was canceled" | 客户端主动断开连接 |
410 | 410001 (CodeSessionExpired) | "session 'sess-abc123' has expired or the bound provider is no longer available; please start a new session" | 会话亲和绑定的 provider 下线,需用新 X-Session-ID 重建会话 |
451 | 451001 (CodeContentFiltered) | "content was filtered by safety policy" | 输入或输出触发内容安全策略 |
500 | 500001 (CodeInternalError) | "internal server error" | 网关内部未预期错误,具体原因见服务端日志 |
502 | 502001 (CodeUpstreamError) | "upstream service error" | 上游模型服务返回 5xx 或不可达 |
503 | 503001 (CodeServiceUnavailable) | "service unavailable" | 网关自身或关键依赖服务不可用 |
504 | 504001 (CodeGatewayTimeout) | "gateway timeout" | 上游响应超时,网关主动中断 |
1.4 错误响应示例
示例 A:API Key 无效(HTTP 401)
{"error": {"type": "authentication_error","code": "401002","message": "invalid api key","source": "gateway","request_id": "req-8f5f2c9e"}}
排查建议:检查请求头
Authorization: Bearer <your-api-key> 中的 API Key 是否正确、是否过期。示例 B:参数非法(HTTP 400)
{"error": {"type": "invalid_request_error","code": "400002","message": "invalid parameter 'model': model is required","source": "client","request_id": "req-2f893f10"}}
排查建议:检查请求体中
model 字段是否正确填写,确认拼写和格式无误。示例 C:上游服务过载(HTTP 502)
{"error": {"type": "upstream_error","code": "bad_gateway","message": "provider overloaded, please retry","source": "upstream","upstream_code": "bad_gateway","upstream_status": 502,"request_id": "req-7d2c4a11"}}
排查建议:上游模型服务暂时过载,建议使用指数退避策略进行重试。
示例 D:触发限流(HTTP 429)
{"error": {"type": "rate_limit_error","code": "429001","message": "rate limit exceeded on dimension: rpm","source": "gateway","request_id": "req-16c2ae01"}}
排查建议:当前请求频率超出限额,请降低调用频率或联系平台提升配额。
1.5 特殊情况
在以下少数场景中,错误响应格式与标准格式略有差异:
链路短路返回
当错误在请求链路早期被拦截时(如鉴权失败在处理器之前),返回简化格式:
{"error": {"type": "gateway_error","code": "401002","message": "invalid api key","request_id": "req-123"}}
与标准格式的区别:
type 固定为 gateway_error,不再细分错误类型没有
source、upstream_code、upstream_status 字段请求体超限(HTTP 413)
例如当请求 body 超过限制时,直接返回:
{"error": {"type": "invalid_request_error","message": "request body too large, max allowed is 2097152 bytes"}}
服务内部异常(HTTP 500)
极少数情况下服务出现非预期异常:
{"error": {"type": "server_error","message": "internal server error"}}
注意:
以上两种情况返回的响应不包含
code、source、request_id 字段。二、Anthropic 兼容协议
如果您使用 Anthropic 兼容协议接入 TokenHub,错误响应遵循 Anthropic 官方格式。
2.1 错误响应结构
{"type": "error","error": {"type": "<错误类型>","message": "<错误描述>","reqid": "<请求唯一标识>"}}
2.2 与标准格式的区别
区别项 | OpenAI 协议 | Anthropic 协议 |
外层结构 | 仅 error 对象 | 外层多一个 "type": "error" |
业务码 | 返回 code 字段 | 不返回 code |
请求 ID 字段名 | request_id | reqid |
错误来源 | 返回 source 字段 | 不返回 source |
2.3 Anthropic 协议错误类型
错误类型(type) | 含义 |
invalid_request_error | 请求参数无效 |
authentication_error | 鉴权失败 |
permission_error | 权限不足 |
not_found_error | 资源不存在 |
rate_limit_error | 限流 |
overloaded_error | 服务过载 |
api_error | 服务端内部错误 |
2.4 示例:限流(HTTP 429)
{"type": "error","error": {"type": "rate_limit_error","message": "rate limit exceeded on dimension: rpm","reqid": "req-123"}}
三、获取帮助与提交工单
提交工单时请提供以下信息:
必要信息 | 说明 |
Request ID | 错误响应中的 request_id(OpenAI 协议)或 reqid(Anthropic 协议),这是定位问题的关键标识。请注意: request_id 是后端排查问题的唯一索引,请务必在工单中提供。没有 request_id 将显著增加问题定位时间。 |
请求时间 | 出错的大致时间点。 |
请求参数 | 使用的 model 名称、endpoint 等。 |
错误响应 | 完整的错误响应 JSON。 |