{
  "version": "2026-10-08",
  "description": "优谷雅言 SDK 统一错误码表。errors 为服务端错误码，warnings 为评测结果里的音频质量警告码，local 为 SDK 本地错误码，compatErrIds 为声通平替层回调里的 errId。各端常量由 tools/gen-errors.mjs 生成。",
  "categories": ["NETWORK", "TIMEOUT", "AUTH", "PERMISSION", "INVALID_PARAM", "NOT_FOUND", "CONFLICT", "RATE_LIMIT", "QUOTA", "SERVER", "UPSTREAM", "AUDIO", "STATE", "CANCELLED", "PROTOCOL", "UNKNOWN"],
  "errors": [
    {"code": 40001, "name": "VALIDATION_ERROR", "http": 400, "category": "INVALID_PARAM", "retryable": false, "message": "请求参数校验失败"},
    {"code": 40100, "name": "UNAUTHORIZED", "http": 401, "category": "AUTH", "retryable": false, "message": "未认证，缺少或无效的凭据"},
    {"code": 40300, "name": "FORBIDDEN", "http": 403, "category": "PERMISSION", "retryable": false, "message": "无权限，例如 API Key 未授权该 coreType"},
    {"code": 40400, "name": "NOT_FOUND", "http": 404, "category": "NOT_FOUND", "retryable": false, "message": "资源不存在"},
    {"code": 40900, "name": "CONFLICT", "http": 409, "category": "CONFLICT", "retryable": false, "message": "资源冲突"},
    {"code": 40901, "name": "IDEMPOTENCY_IN_PROGRESS", "http": 409, "category": "CONFLICT", "retryable": true, "message": "同一幂等键的请求仍在处理中，稍后用同一个键重试"},
    {"code": 40902, "name": "QUOTA_INSUFFICIENT", "http": 409, "category": "QUOTA", "retryable": false, "message": "套餐额度和账户余额均不足"},
    {"code": 40903, "name": "IDEMPOTENCY_KEY_REUSED", "http": 409, "category": "CONFLICT", "retryable": false, "message": "幂等键已用于另一个不同的请求"},
    {"code": 42900, "name": "TOO_MANY_REQUESTS", "http": 429, "category": "RATE_LIMIT", "retryable": true, "message": "请求过多或评测排队超时，按 Retry-After 稍后重试"},
    {"code": 42901, "name": "CONCURRENCY_LIMIT", "http": 429, "category": "RATE_LIMIT", "retryable": true, "message": "并发评测数超出套餐层级限制"},
    {"code": 42902, "name": "TRIAL_REPORT_DAILY_LIMIT", "http": 429, "category": "QUOTA", "retryable": false, "message": "试用层 AI 报告达到每日上限"},
    {"code": 42903, "name": "SANDBOX_DAILY_LIMIT", "http": 429, "category": "QUOTA", "retryable": false, "message": "沙箱密钥当日调用次数达到上限"},
    {"code": 50000, "name": "INTERNAL_ERROR", "http": 500, "category": "SERVER", "retryable": true, "message": "服务器内部错误"},
    {"code": 50010, "name": "FEATURE_NOT_IMPLEMENTED", "http": 500, "category": "SERVER", "retryable": false, "message": "功能未实现"},
    {"code": 50200, "name": "UPSTREAM_SERVICE_ERROR", "http": 502, "category": "UPSTREAM", "retryable": true, "message": "上游评测服务暂不可用"},
    {"code": 2001, "name": "TOKEN_EXPIRED", "http": 401, "category": "AUTH", "retryable": false, "message": "token 已过期，兼容层早期引擎接口也用此码表示缺少鉴权三元组或签名不匹配"},
    {"code": 2002, "name": "TOKEN_INVALID", "http": 401, "category": "AUTH", "retryable": false, "message": "token 无效，兼容层早期引擎接口也用此码表示时间戳超窗"},
    {"code": 2003, "name": "SIGNATURE_VERIFICATION_FAILED", "http": 401, "category": "AUTH", "retryable": false, "message": "签名验证失败，兼容层早期引擎接口也用此码表示 appKey 不存在"},
    {"code": 2004, "name": "SESSION_EXPIRED", "http": 401, "category": "AUTH", "retryable": false, "message": "会话已过期"},
    {"code": 2005, "name": "TOKEN_BLACKLISTED", "http": 401, "category": "AUTH", "retryable": false, "message": "token 已被列入黑名单"},
    {"code": 2006, "name": "API_KEY_INVALID", "http": 401, "category": "AUTH", "retryable": false, "message": "API Key 无效"},
    {"code": 2007, "name": "API_KEY_EXPIRED", "http": 401, "category": "AUTH", "retryable": false, "message": "API Key 已过期"},
    {"code": 2008, "name": "TOKEN_METADATA_NOT_FOUND", "http": 401, "category": "AUTH", "retryable": false, "message": "token 元数据丢失"},
    {"code": 2009, "name": "TOKEN_REFRESH_FAILED", "http": 401, "category": "AUTH", "retryable": false, "message": "token 刷新失败"},
    {"code": 2010, "name": "API_KEY_NOT_FOUND", "http": 401, "category": "AUTH", "retryable": false, "message": "API Key 不存在"},
    {"code": 2011, "name": "API_KEY_DISABLED", "http": 401, "category": "AUTH", "retryable": false, "message": "API Key 已禁用"},
    {"code": 2012, "name": "API_KEY_QUOTA_EXCEEDED", "http": 400, "category": "QUOTA", "retryable": false, "message": "API Key 配额已超限"},
    {"code": 3001, "name": "RATE_LIMIT_EXCEEDED_IP", "http": 429, "category": "RATE_LIMIT", "retryable": true, "message": "请求过于频繁，按来源地址限流"},
    {"code": 3002, "name": "RATE_LIMIT_EXCEEDED_USER", "http": 429, "category": "RATE_LIMIT", "retryable": true, "message": "请求过于频繁，按用户限流"},
    {"code": 3003, "name": "RATE_LIMIT_EXCEEDED_API_KEY", "http": 429, "category": "RATE_LIMIT", "retryable": true, "message": "请求过于频繁，按 API Key 限流"},
    {"code": 1004, "name": "USER_DISABLED", "http": 400, "category": "PERMISSION", "retryable": false, "message": "用户已禁用"},
    {"code": 1005, "name": "USER_LOCKED", "http": 400, "category": "PERMISSION", "retryable": false, "message": "用户已锁定"},
    {"code": 1012, "name": "ACCOUNT_DISABLED", "http": 400, "category": "PERMISSION", "retryable": false, "message": "账户已禁用"},
    {"code": 1013, "name": "ACCOUNT_FROZEN", "http": 400, "category": "PERMISSION", "retryable": false, "message": "账户已冻结"},
    {"code": 1310, "name": "ACCOUNT_BALANCE_INSUFFICIENT", "http": 400, "category": "QUOTA", "retryable": false, "message": "账户余额不足"},
    {"code": 1311, "name": "ACCOUNT_LEDGER_CONFLICT", "http": 400, "category": "CONFLICT", "retryable": true, "message": "账目并发冲突，重试即可"}
  ],
  "warnings": [
    {"code": 1001, "name": "NO_VALID_AUDIO", "category": "AUDIO", "retryable": false, "message": "No valid audio detected!", "hint": "未检测到有效音频，分数不可信，需要重录"},
    {"code": 1002, "name": "VOLUME_TOO_LOW", "category": "AUDIO", "retryable": false, "message": "Audio volume too low!", "hint": "音量过低"},
    {"code": 1003, "name": "VOLUME_TOO_HIGH", "category": "AUDIO", "retryable": false, "message": "Audio volume too high!", "hint": "音量过高，有截幅"},
    {"code": 1004, "name": "AUDIO_NOISY", "category": "AUDIO", "retryable": false, "message": "Audio noisy!", "hint": "环境噪声明显"},
    {"code": 1005, "name": "AUDIO_INCOMPLETE", "category": "AUDIO", "retryable": false, "message": "Audio not complete!", "hint": "音频疑似不完整，分数仅供参考"},
    {"code": 1009, "name": "SCORER_DEGRADED", "category": "AUDIO", "retryable": true, "message": "scorer degraded", "hint": "部分评分组件临时降级，重新提交可能恢复"}
  ],
  "local": [
    {"code": 90001, "name": "NETWORK_ERROR", "category": "NETWORK", "retryable": true, "message": "网络错误，连接失败或被重置"},
    {"code": 90002, "name": "TIMEOUT", "category": "TIMEOUT", "retryable": true, "message": "连接或读取超时"},
    {"code": 90003, "name": "CANCELLED", "category": "CANCELLED", "retryable": false, "message": "调用方取消了请求"},
    {"code": 90004, "name": "CLIENT_CLOSED", "category": "STATE", "retryable": false, "message": "客户端已关闭"},
    {"code": 90005, "name": "PROTOCOL_ERROR", "category": "PROTOCOL", "retryable": false, "message": "响应或帧无法解析"},
    {"code": 90006, "name": "RECONNECT_EXHAUSTED", "category": "NETWORK", "retryable": false, "message": "实时连接重连次数用尽"},
    {"code": 90007, "name": "RESULT_TIMEOUT", "category": "TIMEOUT", "retryable": true, "message": "结束后等待终评结果超时"},
    {"code": 90008, "name": "REPLAY_BUFFER_OVERFLOW", "category": "STATE", "retryable": false, "message": "重连重放缓冲超过上限"},
    {"code": 90009, "name": "INVALID_STATE", "category": "STATE", "retryable": false, "message": "当前会话状态不允许该操作"},
    {"code": 90010, "name": "INVALID_ARGUMENT", "category": "INVALID_PARAM", "retryable": false, "message": "调用参数不合法"},
    {"code": 90011, "name": "TLS_ERROR", "category": "NETWORK", "retryable": false, "message": "证书校验失败"},
    {"code": 90101, "name": "AUDIO_TOO_SHORT", "category": "AUDIO", "retryable": false, "message": "音频短于 1 秒"},
    {"code": 90102, "name": "AUDIO_TOO_LONG", "category": "AUDIO", "retryable": false, "message": "音频长于 300 秒，整段上传大于 50 MB，或实时评测一轮大于 10 MB"},
    {"code": 90103, "name": "AUDIO_SILENT", "category": "AUDIO", "retryable": false, "message": "音频全程静音"},
    {"code": 90104, "name": "AUDIO_LOW_VOLUME", "category": "AUDIO", "retryable": false, "message": "音量过低"},
    {"code": 90105, "name": "AUDIO_FORMAT_UNSUPPORTED", "category": "AUDIO", "retryable": false, "message": "不是 16 位 PCM 或采样率低于 16000"},
    {"code": 90201, "name": "RECORDER_PERMISSION_DENIED", "category": "PERMISSION", "retryable": false, "message": "没有麦克风权限"},
    {"code": 90202, "name": "RECORDER_UNAVAILABLE", "category": "STATE", "retryable": false, "message": "麦克风被占用或不可用"},
    {"code": 90203, "name": "RECORDER_ERROR", "category": "STATE", "retryable": false, "message": "录音过程出错"}
  ],
  "compatErrIds": [
    {"errId": 20009, "message": "网络或服务端临时故障，可重评，autoRetry 默认重评此码"},
    {"errId": 60001, "message": "音频文件不存在或不可读"},
    {"errId": 60002, "message": "音频为空"},
    {"errId": 60003, "message": "coreType 不支持"},
    {"errId": 60004, "message": "麦克风不可用或没有录音权限"},
    {"errId": 60005, "message": "音频短于 1 秒"},
    {"errId": 60006, "message": "refText 为空"},
    {"errId": 60007, "message": "引擎未初始化"},
    {"errId": 60008, "message": "引擎正忙，上一次评测未结束"},
    {"errId": 60009, "message": "音频大于 50 MB 或长于 300 秒"}
  ],
  "httpFallback": {"400": "INVALID_PARAM", "401": "AUTH", "403": "PERMISSION", "404": "NOT_FOUND", "405": "INVALID_PARAM", "408": "TIMEOUT", "409": "CONFLICT", "413": "INVALID_PARAM", "415": "INVALID_PARAM", "422": "INVALID_PARAM", "425": "RATE_LIMIT", "429": "RATE_LIMIT", "500": "SERVER", "501": "SERVER", "502": "UPSTREAM", "503": "UPSTREAM", "504": "UPSTREAM"},
  "retryableHttp": [408, 425, 429, 500, 502, 503, 504]
}
