错误码与请求 ID
本文是平台接口错误的参考:错误信封的字段、每个稳定错误码的含义与处理方式、开发者平台接口(/api/dev)的错误,以及怎样用请求 ID 查到一次调用。错误信封里的 docUrl 指向本页上对应错误码的位置。
错误信封
HTTP 状态码 ≥ 400 时,/open/v1 与 /app/v1 的接口都返回同一个嵌套的错误信封:
{
"error": {
"code": "scope_required",
"message": "this call needs the scope platform:ping",
"requestId": "9f2c7a3b4e1d5f60",
"docUrl": "https://dev.${DOMAIN}/docs/errors#scope_required",
"details": {}
}
}code:稳定的错误类型标识。程序按它分支,不按message分支。message:给人看的说明,语言随请求头Accept-Language。requestId:这次调用的标识,与响应头X-Request-Id相同。docUrl:本页上这个错误码的地址,形如https://dev.${DOMAIN}/docs/errors#<code>。details:结构化的补充信息;没有时是{}。例如ambiguous_customer在details.candidates里给出候选客户。
两个 SDK 都把信封读成一个错误值:Go 是 *raise.Error(err.Code、err.RequestID),TypeScript 是 SDK 抛出的错误对象。
常见错误码
code | HTTP | 含义 | 怎么办 |
|---|---|---|---|
invalid_request | 400 | 请求格式非法或请求正文超过限制(如非 JSON 格式或超过 4 KiB) | 检查并修正请求正文格式,减小体积后重试。 |
unauthorized | 401 | 缺少认证信息或身份验证未通过 | 检查认证头格式与凭据是否有效。 |
forbidden | 403 | 权限不足或拒绝访问 | 检查当前凭据是否具备操作该资源的权限。 |
not_found | 404 | 请求的资源或路径不存在 | 核对请求 URL 路径及资源 ID 是否正确。 |
method_not_allowed | 405 | 该端点不支持当前 HTTP 方法 | 更换为端点允许的 HTTP 请求方法。 |
conflict | 409 | 资源当前状态与该操作存在冲突 | 检查业务对象最新状态后重试。 |
payload_too_large | 413 | 请求正文超出接口允许的最大限制 | 缩减正文大小或分批次提交。 |
validation_failed | 422 | 请求参数或业务数据校验失败 | 查看 details 字段中的错误信息并修正字段。 |
rate_limited | 429 | 凭证或接口调用频次超出限制 | 读取 Retry-After 头,等待指定秒数后再发起请求。 |
internal | 500 | 服务端处理发生内部异常 | 稍后重试,持续失败时提供 requestId 联系平台排查。 |
not_implemented | 501 | 该功能或接口在当前环境中未实现或未接入 | 确认当前系统部署是否已启用该服务依赖。 |
unavailable | 503 | 服务暂时不可用或未能读取到凭据/客户数据 | 采用退避算法稍后重试。 |
token_required | 401 | 请求未携带 Authorization: Bearer 令牌头 | 先调用令牌端点换取访问令牌,并在请求头中附带。 |
invalid_token | 401 | 访问令牌无效、签名错误或已过期 | 重新换取有效的访问令牌后重试。 |
invalid_credential | 401 | 客户端 ID 或密钥错误,或前缀格式不正确 | 检查传入的客户端 ID 与 Secret 是否正确。 |
invalid_client | 401 | OAuth 端点客户端身份认证失败 | 检查 Basic 认证头或正文中的密钥参数。 |
unsupported_grant_type | 400 | 不支持的授权类型参数 | 仅使用 client_credentials 或 urn:raise:grant-type:customer。 |
tenant_required | 400 | 换取令牌时未提供租户参数 | 商店应用在换取令牌时正文必须包含 tenant 参数。 |
wrong_environment | 403 | 凭证与目标租户的环境不匹配 | 测试环境密钥仅能访问测试企业,正式密钥仅能访问真实租户。 |
credential_ended | 401 | 凭证已吊销、过期或租户已被暂停/关闭 | 更换有效凭证,或联系管理员恢复租户状态。 |
address_not_allowed | 403 | 请求来源 IP 不在凭据的 IP 白名单中 | 确认来源 IP,在开发者平台将出口 IP 加入白名单。 |
not_installed | 403 | 目标租户未安装该应用,或安装已被停用/卸载 | 请租户管理员在工作台确认已安装并启用应用。 |
no_scope | 403 | 该凭证或应用当前未被授予任何有效权限范围 | 联系租户管理员在管理后台为应用配置并保存权限范围。 |
scope_required | 403 | 当前调用缺少对应接口要求的权限范围 | 申请所需权限范围并由管理员同意,然后换取新令牌。 |
customer_token_required | 403 | 该端点要求客户令牌,当前出示的是租户令牌 | 先通过客户手机号断言换取客户令牌后再调用。 |
assertion_stale | 401 | 客户断言已超过 10 分钟(写操作安全限制) | 使用客户手机号重新换取客户令牌后重试写操作。 |
invalid_phone | 422 | 手机号格式无法识别 | 提供大陆 11 位有效手机号或符合 E.164 规范的国际号码。 |
ambiguous_customer | 409 | 该手机号在租户中匹配到多个客户档案 | 从 details.candidates 选取客户 ID,并在请求中带上 customer_id。 |
too_many_attempts | 429 | 同一 IP 一分钟内认证失败次数满 30 次 | 等待 Retry-After(60 秒)后方可重新尝试。 |
idempotency_conflict | 409 | 相同幂等键附带了不同的请求方法、路径或正文 | 更换全新的 Idempotency-Key 重新提交。 |
idempotency_in_progress | 409 | 相同幂等键的首个请求仍在处理中 | 稍作等待,切勿使用不同参数重试。 |
condition_failed | 412 | 并发写入或版本前置条件检查不满足 | 重新拉取最新数据版本后再提交更新。 |
表里没有的 code 按 HTTP 状态处理:4xx 先改请求,5xx 用退避重试。
开发者平台接口的错误
开发者平台接口(https://dev.${DOMAIN}/api/dev/…,门户、k3 命令行和 CI 调用的接口)的错误也用上面的信封,code 按 HTTP 状态取通用的几个:
| HTTP | code | 常见原因 | 怎么办 |
|---|---|---|---|
| 400 | invalid_request | 请求正文不是合法的 JSON | 修正正文。 |
| 401 | unauthorized | 没有令牌,或令牌过期、无效 | 重新登录门户,或用 API 凭证重新换令牌,见 认证与凭证。 |
| 403 | forbidden | 角色不够,或账号不属于一个启用中的开发者组织 | 见下文「角色不够」。 |
| 404 | not_found | 资源不存在,或属于别的开发者组织(两种情况答得一样) | 核对 ID 和所在的组织。 |
| 409 | conflict | 与当前状态冲突,例如应用 ID 已被别的组织占用、测试企业里还没装这个应用 | 读 message,先做它说的前一步。 |
| 409 | app_id_reserved | 应用 ID 格式正确但被保留:平台名称,或只能由平台运营转交的目录应用(如 distribution) | 换一个自己的 ID;要接手目录应用,请平台运营转交。 |
| 422 | validation_failed | 字段不合规则,例如应用 ID 的格式,或测试企业管理员的邮箱已是平台的账号(adminEmail "…" is already in use) | 读 message 修正字段。 |
| 501 | not_implemented | 这个部署没有开这项服务 | 联系平台运营。 |
| 503 | unavailable | 依赖的服务暂时不可用,例如部署不能发邮件时的自助注册 | 稍后重试;自助注册见 快速开始。 |
message 写明具体原因。较早的平台版本在 /api/dev 上返回平铺的 {"error": "…"},没有 code 和 requestId,请求 ID 只在响应头 X-Request-Id 里;要兼容这样的平台,error 是字符串时把它当作 message。
角色不够
开发者平台接口只接受开发者组织的成员,并且要有开发者角色。HTTP 403 的 message 有两种:
requires one of: isv.developer:令牌里没有在你所属组织生效的开发者角色。角色只在你账号所属的那个组织里算数,在别的组织授予的不算。请组织管理员在门户的「团队」页确认你的账号有「开发者」角色。API 凭证建出来就带开发者角色。your account does not belong to an active developer organisation:你的账号所在的组织不是开发者组织,或者这个开发者组织已被停用。
令牌里有 isv.developer、平台仍然答 403 时,把 requestId(或响应头 X-Request-Id)交给平台运营排查。
用请求 ID 排查
每个响应都带 X-Request-Id,出错时它也在信封的 requestId 里。向平台报障时附上它。你自己也可以用它查这次调用:
- 开发者门户:应用详情的「日志」页签列出每次调用和它的请求 ID,「错误」页签列出应用的错误。
- 命令行:
k3 logs <应用 ID>列出调用,k3 logs <应用 ID> --errors列出错误分组,见 本地开发与测试企业。 - 接口:
GET https://dev.${DOMAIN}/api/dev/apps/${APP_ID}/requests/${REQUEST_ID}返回带这个请求 ID 的错误记录与调用日志,两个环境都查;查不到时是两个空列表。
k3 api GET /api/dev/apps/${APP_ID}/requests/${REQUEST_ID}正式环境的记录不写是哪家企业;测试环境只写出你自己组织的测试企业。