OpenAI API 400 invalid_request_error 怎么解决?
简答:OpenAI API 返回 400,通常表示请求已经到达接口,但请求体、参数或配置没有通过校验。先保存 HTTP 状态、错误响应和 request ID,再按 error.param 指向的字段修改;不要把 400 当成网络问题反复重试。
定义:OpenAI API 的 400 Bad Request 是请求校验失败,常见类型包括 invalid_request_error,具体原因应以响应中的 error.message、error.param 和 error.code 为准。
先做三步速查:错误字段、最小请求、成功判定
截至 2026 年 11 月 9 日,官方文档将 400 请求错误描述为输入或配置无效、过大,修复动作应围绕响应中的错误字段展开。官方错误指南还列出了一类明确的 400:项目不允许请求使用的 service_tier。查看官方错误码说明
| 先检查什么 | 怎么判断 | 下一步 |
|---|---|---|
| HTTP 状态 | 是否确实为 400,而不是 401、403、404 或 429 | 先分离认证、权限、路径和限流问题 |
| error 对象 | 读取 message、param、code | 优先修复 param 指向的字段 |
| 最小请求 | 仅保留模型和最小输入后是否成功 | 成功后逐项恢复参数,定位新增字段 |
| 响应头 | 记录 request ID,不记录 API Key | 持续失败时连同脱敏请求提交给维护者 |
成功判定不是“连接没有报错”,而是收到 2xx 响应并得到符合当前接口结构的响应体。若最小请求仍返回 400,应继续核对实际主机、路径、HTTP 方法、模型 ID 和接口类型;若最小请求成功,再逐项恢复 tools、结构化输出、服务层级等可选参数。
用最小 curl 请求缩小范围
下面的命令只使用占位符,不假设某个第三方兼容网关的真实域名或模型 ID。将 API_HOST、API_KEY 和 MODEL_ID 替换为你正在使用的服务文档中已核实的值。对于原生 Chat Completions,请求体使用 messages;该接口的官方定义是向 /chat/completions 发送包含消息列表的请求。查看 Chat Completions 参数定义
curl -i "$API_HOST/chat/completions" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" --data '{"model":"MODEL_ID","messages":[{"role":"user","content":"Reply with OK"}]}'
- 先看最终 URL:确认客户端没有重复拼接路径,例如 Base URL 已包含版本路径时,SDK 是否又自动添加了一段路径。
- 再看方法和请求头:方法应与接口文档一致;JSON 请求通常需要
Content-Type: application/json,认证头中的 Key 不要带多余空格或换行。 - 最后看完整响应:使用
-i同时查看状态码和响应头,保存响应体中的error.message、error.param、error.code以及 request ID。
如果这个最小请求返回 2xx,说明连接、认证、基本路径和基础请求体大概率已经通过,接下来不要一次性恢复全部业务参数。每次只增加一个字段,并在日志中记录字段名和类型,不记录提示词全文、Key、文件内容或用户隐私。
按错误字段排查 JSON、接口和参数组合
1. JSON 或 Content-Type 不正确
先在本地解析请求体,检查逗号、引号、括号、布尔值和数字类型。不要把 JSON 字符串再次包成字符串,也不要把数组字段误传成对象。若服务端返回的是 HTML、网关默认页面或没有结构化 error 对象,应先确认实际请求是否到达了预期 API 主机。
2. Chat Completions 与 Responses 字段混用
Chat Completions 的核心请求字段是 model 和 messages;Responses API 使用 input,请求路径也不同。官方 Responses API 参考将 input 定义为字符串或输入项目数组。不要把一个接口的字段原样复制到另一个接口。查看 Responses API 请求定义
| 接口 | 核心路径 | 常见输入字段 | 排查重点 |
|---|---|---|---|
| Chat Completions | /chat/completions | model、messages | 消息数组、角色、内容类型和模型参数 |
| Responses | /responses | model、input | 输入项目类型、工具和文本输出配置 |
3. 模型不支持某个参数
接口文档明确提示,不同模型的参数支持可能不同,尤其是较新的推理模型。出现 400 时,先删除最近新增的 temperature、tools、response_format、音频或推理相关参数,再逐项加回。不要因为字段在某个模型示例中出现,就假设所有模型都接受它。查看模型参数支持说明
4. 上下文或请求体过大
如果 error.message 指向输入过大、上下文超限或工具定义过大,应减少历史消息、截短工具返回、压缩重复指令,并重新计算输入与输出预算。不要原样重试同一个请求,因为请求内容没有改变,重试通常不会改变校验结果。
5. service_tier 不被项目允许
官方错误文档说明,项目不允许所请求或解析出的服务层级时,会返回 400 invalid_request_error,并可能将 error.param 指向 service_tier。检查项目和组织设置中的允许层级;如果代码显式设置了该字段,改为项目允许的值。若使用 auto 或省略字段也触发此错误,需要检查项目默认解析出的层级,而不是只删除代码字段。查看 service_tier 官方排查说明
Python、JavaScript 与兼容网关的错误记录方式
官方 JavaScript/TypeScript SDK 在收到非 2xx 响应时会抛出 APIError 子类;400 对应 BadRequestError,示例中可读取状态码、响应头和 request ID。SDK 默认会对部分连接错误、408、409、429 及 5xx 做重试,但 400 不应在请求未修改时盲目重试。查看官方 SDK 错误处理说明
try { const result = await client.chat.completions.create({ model: process.env.MODEL_ID, messages: [{ role: "user", content: "Reply with OK" }] }); console.log(result.id); } catch (err) { if (err instanceof OpenAI.APIError) { console.error({ status: err.status, request_id: err.requestID, message: err.message }); } throw err; }
Python 或其他 SDK 也应采用同一套日志原则:记录 HTTP 状态、错误类型、错误码、参数名、request ID、实际接口类型和经过脱敏的模型 ID;不要记录完整 Authorization、原始 API Key、用户隐私、完整文件内容或未脱敏提示词。若使用 OpenAI-compatible 网关,额外记录“客户端最终请求 URL”和网关返回的原始响应体,因为兼容层可能只实现部分字段,不能直接把原生 API 的全部参数假设为可用。
修复后再重试:JSON、路径、字段名、字段类型、模型参数和输入长度改变后,可以重新发送。不要原样重试:错误字段未变化、模型明确不支持参数、项目层级不允许、请求体仍然超限时,应先修改配置。持续失败时,按官方建议提交 request ID、时间、接口、模型、错误信息和脱敏请求数据。
一张 400 排错清单
- 主机与路径:确认客户端最终访问的主机、路径和方法,而不是只看配置界面中的 Base URL。
- 认证:400 通常不是认证错误;若状态实际为 401,应转到 API Key、组织或项目权限排查。
- 接口字段:Chat Completions 检查
messages,Responses 检查input,不要交叉使用。 - 模型能力:核对模型 ID 和参数支持,优先移除最近添加的可选字段。
- 输入规模:压缩历史消息、工具结果和 schema,确认请求体没有超过接口或模型限制。
- 错误记录:保存
status、message、param、code、request ID 和时间,所有敏感字段先脱敏。 - 兼容接口:以当前网关的接口文档为准,未核实的模型、域名、路径和参数不要直接写入生产配置。
常见问题
OpenAI API 400 和 401 有什么区别?
400 表示请求内容或配置没有通过校验,重点看 error.message、error.param 和 error.code;401 表示认证凭据或相关身份信息有问题。先确认实际 HTTP 状态,不要仅凭客户端显示的“请求失败”判断。
400 invalid_request_error 可以直接重试吗?
如果请求体、字段、模型参数或项目配置没有改变,不建议原样重试。应先根据 error.param 或 error.message 修复请求;只有修复后才重新发送。SDK 对 400 不属于默认自动重试的主要类别。
为什么最小请求成功,加入 tools 后又返回 400?
这通常说明基础连接、认证和核心请求体已通过,新增的工具定义、参数类型、JSON Schema 或模型能力需要继续核对。一次只恢复一个工具或字段,并保存对应响应,避免同时修改多个变量。
Responses API 能不能直接使用 messages?
不能简单假设两者字段完全相同。Chat Completions 的核心输入是 messages,Responses API 的核心输入是 input;请根据实际路径和官方接口定义组织请求体。
如何向技术支持提供 400 错误信息?
提供发生时间、HTTP 状态、request ID、接口类型、模型 ID、脱敏后的 error 对象和最小复现请求。删除 API Key、Authorization、用户隐私、完整文件内容和敏感提示词后再提交。
