项目:codeg(桌面端 · 待办任务 · ACP + Codex CLI)
严重度:高(任务空转、无输出、无报错,用户无法自行恢复)
影响模块:工作区任务引擎、ACP 会话持久化、模型网关转发
问题描述
在上下文很大的待办任务里,模型偶发地生成一条「写到一半」的工具调用(function_call 的 arguments 不是合法 JSON)。Codex CLI 解析失败后,把这条坏记录连同「解析失败」的结果一起写进了会话历史。此后每次在该任务点击「继续」,完整历史都会被原样重发给模型接口,上游因 Assistant tool call function.arguments must be valid JSON 返回 400,本地网关把 400 包装成 502,客户端把任务静默置回「待审阅」——没有产出,界面上也看不到真实错误。用户反复点「继续」都会同样失败(本机观察到的现象是约 5~6 秒内空转后回到 review)。
复现特征 / 触发条件
- 待办任务经过多轮反馈,上下文非常大(本案例约 50 万+ token,第 9~12 轮)
- 模型生成的是超长工具调用(多为
shell_command,命令内嵌大段文本 / heredoc),输出中途被截断
- 第一次断掉后,后续每一轮都稳定失败,失败轮次没有任何 diff 或消息产出
- 会话 JSONL 中存在
arguments 无法被 json.loads 解析的 function_call(报错形如 Unterminated string starting at ... / EOF while parsing a string)
根因分析
- 模型输出被截断(疑似命中单次输出长度上限或上游流中断),产出的
function_call.arguments 不是合法 JSON;客户端解析失败,记录 failed to parse function arguments: EOF while parsing a string ...
- 客户端把这条坏 function_call 连同它的「解析失败」output 一起持久化进会话历史(rollout JSONL)
- 之后每次 resume / 点「继续」,完整历史(含这条坏记录)被重新提交给模型 API;上游严格校验每条 assistant tool call 的
arguments 必须是合法 JSON,返回 400
- 本地网关把上游 400 转成 HTTP 502;客户端统一按失败处理,任务引擎静默归为 review,不落
failure_reason / last_error,用户看不到真实原因
期望行为
- 会话历史在持久化或下一次提交前,对无法解析的 function_call 做清洗(丢弃该条及其 output,或修复 / 重新生成),避免坏记录永远卡死后续轮次
- 单轮内若模型产出无法解析 arguments 的 tool call,客户端应主动重试一次让模型重新生成,而不是直接落历史
- 任务轮次失败时,必须把真实错误(上游 400 的具体 message)写入任务并向用户展示,不能静默回到待审阅
- 网关转发失败时透传上游状态码与错误体,不要统一升级成 502、丢失真实原因
建议方案
- 会话历史加载 / 追加时做合法性校验:
function_call.arguments 非合法 JSON 的项(及其对应 output)从后续请求输入中剔除
- 对解析失败的 tool call 触发一次修复重试(让模型重新生成该调用)
- 失败路径透传:work_task 记录
failure_reason / last_error 为上游原文(如 Assistant tool call function.arguments must be valid JSON.),并在 UI 展示
- 网关
forward_failed 保留上游 status / message,避免 400 → 502 的信息丢失
诊断样例(本机已复现两次)
- 客户端:
unexpected status 502 Bad Gateway: Upstream request failed, url: http://localhost:8080/responses
- 网关:
openai.forward_failed ... error="upstream error: 400 message=Error from provider (Console Go): Upstream request failed: [400] Assistant tool call function.arguments must be valid JSON."
- 会话历史:一条截断的
shell_command(如 python -m pytest ... 或内嵌文档 heredoc),解析报 Unterminated string starting at: line 1 column ...
项目:codeg(桌面端 · 待办任务 · ACP + Codex CLI)
严重度:高(任务空转、无输出、无报错,用户无法自行恢复)
影响模块:工作区任务引擎、ACP 会话持久化、模型网关转发
问题描述
在上下文很大的待办任务里,模型偶发地生成一条「写到一半」的工具调用(function_call 的
arguments不是合法 JSON)。Codex CLI 解析失败后,把这条坏记录连同「解析失败」的结果一起写进了会话历史。此后每次在该任务点击「继续」,完整历史都会被原样重发给模型接口,上游因Assistant tool call function.arguments must be valid JSON返回 400,本地网关把 400 包装成 502,客户端把任务静默置回「待审阅」——没有产出,界面上也看不到真实错误。用户反复点「继续」都会同样失败(本机观察到的现象是约 5~6 秒内空转后回到 review)。复现特征 / 触发条件
shell_command,命令内嵌大段文本 / heredoc),输出中途被截断arguments无法被json.loads解析的 function_call(报错形如Unterminated string starting at .../EOF while parsing a string)根因分析
function_call.arguments不是合法 JSON;客户端解析失败,记录failed to parse function arguments: EOF while parsing a string ...arguments必须是合法 JSON,返回 400failure_reason/last_error,用户看不到真实原因期望行为
建议方案
function_call.arguments非合法 JSON 的项(及其对应 output)从后续请求输入中剔除failure_reason/last_error为上游原文(如Assistant tool call function.arguments must be valid JSON.),并在 UI 展示forward_failed保留上游 status / message,避免 400 → 502 的信息丢失诊断样例(本机已复现两次)
unexpected status 502 Bad Gateway: Upstream request failed, url: http://localhost:8080/responsesopenai.forward_failed ... error="upstream error: 400 message=Error from provider (Console Go): Upstream request failed: [400] Assistant tool call function.arguments must be valid JSON."shell_command(如python -m pytest ...或内嵌文档 heredoc),解析报Unterminated string starting at: line 1 column ...