# 媒体错误处理
> 媒体接口报错排查与处理:错误响应格式、每个错误码的 HTTP 状态和处理方式、常见报错原文对照,以及什么时候该重试、什么时候不能重新提交。
## 错误形状
提交、查询或下载失败时,响应体为:
```json
{
"error": {
"code": "invalid_request",
"message": "Invalid media request fields or parameter types",
"stage": "validation",
"retryable": false
},
"request_id": "req_example"
}
```
| 字段 | 说明 |
| --- | --- |
| `error.code` | 稳定的错误码,程序据此分支处理,见下方两张表 |
| `error.message` | 英文的具体原因,直接说明哪个字段或组合不对;原文对照见“常见报错对照” |
| `error.stage` | 出错环节:`validation`(请求校验)、`submission`(提交厂商)、`generation`(生成)、`delivery`(结果交付)、`billing`(账务) |
| `error.retryable` | `true` 表示稍后重试当前操作可能成功:提交使用原幂等键与原请求体,查询或下载重试对应的读取请求;不代表可以重新生成 |
| `request_id` | 本次请求的标识,也在响应头 `X-Oneapi-Request-Id` 中;联系平台排查时提供 |
任务查询成功(HTTP 200)也可能返回生成失败或交付错误,请同时检查任务 `status`、`error` 和 `artifacts[].error`。交付错误不把已经成功的生成改成失败:任务可保持 `succeeded`,查询中的错误为 `provider_unavailable`、`stage: "delivery"`、`retryable: true`;签名产物下载失败则返回 HTTP 502 和同样的错误语义。
## 请求与授权
| 错误码 | HTTP | 含义 | 处理 |
| --- | --- | --- | --- |
| `invalid_request` | 400 | JSON 格式、字段类型、取值范围、显式 `null` 或字段组合不合法 | 读 `message`,按“常见报错对照”修正后再提交 |
| `unsupported_parameter` | 400 | 当前模型不接受该字段、厂商选项或素材角色 | 删除该字段;可接受的字段见[模型列表:媒体模型返回字段](models.md#models-media-fields) |
| `unsupported_operation` | 400 | 当前模型或任务状态不支持此操作,例如取消 | 不要重试该操作 |
| `idempotency_conflict` | 409 | 同一个 `Idempotency-Key` 已用于内容不同的请求 | 新的生成请求换一个新键 |
| `idempotency_in_progress` | 409 | 同键的原请求仍在受理或恢复中 | 等待响应头 `Retry-After` 的秒数后,用同一个键和同一请求体重放 |
| `model_not_found` | 404 | 模型 ID 拼错、不在媒体协议开放,或单模型查询时当前密钥看不到 | 从 `GET /media/v1/models` 的结果复制 ID |
| `model_not_authorized` | 401 / 403 | 没带密钥或密钥无效(401);密钥没有该模型权限、不属于企业预算主体,或签名下载链接过期(403) | 检查 `Authorization` 头;联系管理员授权;下载链接过期时重新查询任务 |
| `insufficient_budget` | 402 / 403 | 额度或预算不足 | 联系管理员调整额度;已提交的任务仍可查询 |
| `rate_limited` | 429 | 请求过于频繁 | 等几秒后重试;轮询请按[任务查询与结算](media-tasks.md)的建议间隔 |
## 文件与任务
| 错误码 | HTTP | `stage` | 含义 | 处理 |
| --- | --- | --- | --- | --- |
| `file_not_found` | 404 | `validation` | 文件不存在或不在当前企业可见范围 | 核对 `file_id`,或重新上传 |
| `file_expired` | 410 | `validation` | 临时参考文件已过期 | 重新上传后使用新的 `file_id` |
| `asset_not_ready` | 409 | `validation` | 素材还在审核、未通过或类型不符 | 等审核通过;不要重复创建同一素材 |
| `asset_not_authorized` | 403 | `validation` | 当前企业无权使用该素材 | 改用本企业的素材 |
| `task_not_found` | 404 | `validation` | 任务不存在、无权查看,或属于其他协议 | 核对任务 ID,并用提交时的接口查询 |
| `provider_rejected` | 502 或任务内 | `submission` / `generation` | 提交被拒绝或任务生成失败,具体原因见安全错误摘要 | 已有任务先查询并核对账务;确认失败原因后,再决定是否修改输入发起新的生成 |
| `provider_unavailable` | 503 / 504 或任务内 | `submission` | 厂商暂时不可用,或提交/结果仍待核对 | 没有任务 ID 且已使用幂等键时按原请求重放;已有 ID 或 `reconciling` 时查询原任务 |
| `provider_unavailable` | 502(签名下载)或 HTTP 200 的任务内 | `delivery` | 生成已成功,但产物暂时无法读取;`retryable: true` | 重试原下载,或查询原任务取得当前产物信息和新链接;不要重新生成 |
| `internal_error` | 500 | `validation` / `submission`,以响应为准 | 平台内部处理失败 | 按下表区分提交与读取;保存 `request_id`,持续失败时联系平台 |
错误码可能新增,已有错误码的含义保持不变。遇到不认识的错误码时,结合当前操作、HTTP 状态、`stage` 和 `retryable` 处理,不能仅凭 5xx 重新生成。
## 常见报错对照
以下是提交请求时最常见的 `error.message` 原文。表中 `X` 表示具体字段名,例如 `duration`、`resolution`。
### 通用
| 报错原文 | 原因 | 改法 |
| --- | --- | --- |
| Invalid media request fields or parameter types | 有未定义的顶层字段(多为拼写错误,如 `aspectRatio`),或字段类型错误(如 `"duration": "5"`、`"n": "2"`) | 字段名用小写加下划线;数字不要加引号 |
| Explicit null values are not supported | 某个字段传了 `null` | 不需要的字段直接省略 |
| Model type does not match the submission path | 模型类型与提交地址不一致 | 图片用 `/images/generations`,视频用 `/videos/generations`,3D 用 `/3d/generations` |
| Model is not available through the media protocol | 模型 ID 不是媒体模型,或拼写错误 | 从模型列表复制 ID;文本模型请用[文本模型调用](llm-api.md) |
| Parameter X is not supported by this model | 该模型不接受字段 `X` | 删除该字段 |
| Parameter provider_options.X is not supported by this model | 厂商选项的命名空间或选项名不对 | Seedream / Seedance 用 `volcengine`,GPT Image 用 `openai`,可灵用 `kling`,MiniMax 用 `minimax`,3D 用 `tencent`;只接受该型号声明的选项 |
| Parameter references.role or references.type is not supported by this model | 该模型不支持这种素材角色或类型 | 对照各生成页的输入方式表 |
| Parameter references.asset_id is not supported by this model | 该模型或角色不支持素材库 `asset_id` | 改用 `url` 或 `file_id` |
| X is required | 缺少必填字段,常见为 `prompt is required` | 补充该字段 |
| X must be a string / X must be an integer / X must be a boolean | 厂商选项的类型不对 | 按参数表的类型填写 |
| X has an unsupported value | 取值不在允许列表中,常见于 `resolution` 大小写写错 | 按参数表从允许值中选择 |
| X is outside the supported range | 数字超出范围 | 按参数表调整 |
| X is outside the supported length | 字符串过长或为空 | 调整长度 |
| wait must be between 0 and 50 seconds | `wait` 超出 0–50 | 改为 0–50 的整数 |
| prompt exceeds 32000 bytes | 提示词过长 | 缩短提示词 |
| metadata exceeds 64 KiB | `metadata` 过大 | 只放业务 ID 等少量信息 |
| Media request exceeds 4 MiB | 请求体超过 4 MiB,多因内嵌了 base64 图片 | 先[上传文件](media-files.md),改用 `file_id` |
| Idempotency-Key must contain 1 to 255 visible ASCII characters | 幂等键为空、过长或含中文 | 使用 1–255 个英文、数字或符号 |
| The idempotency key was already used with a different request | 同一个幂等键提交了不同内容 | 新请求换新键;重放时请求体必须完全相同 |
### 参考素材
| 报错原文 | 原因 | 改法 |
| --- | --- | --- |
| Each reference requires exactly one of file_id, asset_id or url | 一项素材同时填了多个来源,或一个都没填 | 每项只填一个 |
| Too many references for role X | 该角色的素材数量超过模型上限 | 按各生成页的数量上限减少 |
| Inline data URLs are only supported for image references | 视频或音频用了 `data:` 内嵌 | 视频、音频先上传或使用 URL |
| media inputs require HTTP(S) URLs or image data URIs; asset IDs are provider-specific | `url` 不是 http/https 地址,或把素材 ID 填进了 `url` | 填完整的公网地址;素材 ID 填到 `asset_id` |
| invalid media URL | URL 格式错误、含用户名密码或 `#` 片段 | 使用干净的完整地址 |
| Reference file exceeds this model's size limit | 上传文件超过该模型的大小上限 | 图片 10 MiB、视频 200 MiB、音频 15 MiB 以内 |
| Reference file media type does not match type | 文件实际类型与 `type` 不一致 | 例如图片文件要配 `"type": "image"` |
| size and aspect_ratio cannot be combined | Seedream 同时传了 `size` 和 `aspect_ratio` | 二选一 |
### 各模型特有
图片、视频和 3D 各模型特有的报错及改法,分别见[图片生成](media-images.md)、[视频生成](media-videos.md)和[3D 生成](media-3d.md)页末的“常见错误”。
Nano Banana 名称含空格,JSON `model` 保留目录 ID,单模型查询路径使用 URL 编码;不要改成 Gemini 能力模板名来绕过 `model_not_found`。GPT Image 的 `n` 只接受 1,参考图最多 2 张;`quality` 和 `background` 放在 `provider_options.openai`,`mask`、流式、透明背景等未支持选项在 Provider 前拒绝。参数和引用校验失败不产生生成;已取得任务后出现结果或交付不明,应继续查原任务和 `billing`,不能推断免费并重复 POST。
## 重试还是查询原任务
| 操作阶段 | 情况 | 正确做法 | 不要做 |
| --- | --- | --- | --- |
| 提交 | 超时、断连或 5xx,尚未拿到任务 ID | 已使用幂等键时,等待后用**原键和原请求体**重放;未使用时保存 `request_id` 联系平台核对 | 换新键,或无幂等键自动重提 |
| 提交 | 409 `idempotency_in_progress` | 按 `Retry-After` 等待后用原键和原请求体重放 | 立即连续重试 |
| 提交 | 400 / 404 等校验错误或明确拒绝 | 按错误原因修正;只有确实要发起新的生成时才使用新键 | 原样重试,或把下载的 502 当作提交拒绝 |
| 提交 | 已拿到任务 `id` | 转为查询原任务 | 再次提交生成 |
| 任务查询 | 查询请求超时、429、5xx 或 `retryable: true` | 等待后重试同一个任务的 GET;429 按限流要求退避 | 重放生成 POST |
| 任务查询 | `queued`、`running` 或 `reconciling` | 按建议间隔查询原任务;`reconciling` 持续不变时提供任务 ID 和 `request_id` 联系平台 | 将待核对当成失败并重提 |
| 任务查询 | `failed`、`expired` 或 `cancelled` | 读取错误摘要并单独核对账务;需要新的生成时再调整输入、使用新键提交 | 因终态自动重提,或假定没有费用 |
| 下载 | HTTP 502、`provider_unavailable`、`stage: "delivery"`、`retryable: true`,或查询提示交付不可用 | 稍后重试原下载 GET;也可查询原任务确认产物状态并取得新链接 | 新建任务或重新生成 |
| 下载 | 链接无效或过期(403) | 使用虚拟密钥查询原任务,取得新签名链接再下载 | 重复使用过期链接或重新生成 |
| 账务 | 生成已结束,但 `billing.status` 仍为 `reserved` / `reconciling` | 继续查询原任务;持续未结算时提供任务 ID 和 `request_id` 联系平台核对 | 为解冻资金重新生成,或把未知金额视为 0 |
没有使用 `Idempotency-Key` 时,平台无法识别重复提交,每次提交都会生成新任务。幂等键的作用域与保留期见[媒体请求约定](media-access.md)。