tool calls sometimes fail because the model emits truncated JSON in `function_call.arguments`

Open 💬 0 comments Opened Apr 27, 2026 by hac425xxx

What version of Codex CLI is running?

codex-cli 0.125.0

What subscription do you have?

pro

Which model were you using?

_No response_

What platform is your computer?

_No response_

What terminal emulator and version are you using (if applicable)?

_No response_

What issue are you seeing?

When Codex runs with a weaker model, tool calls sometimes fail because the model emits truncated JSON in function_call.arguments.

The user-visible symptom is a log/error like:

codex_core::tools::router: error=failed to parse function arguments: EOF while parsing a string at line ...

From local source inspection, the root issue is not in tools::router itself. The router is only where the error gets logged while dispatching the tool call. The main parse failure comes from tool handlers that do serde_json::from_str(arguments), especially the shared handler path in codex-rs/core/src/tools/handlers/mod.rs, with parallel copies in:

  • codex-rs/core/src/tools/handlers/plan.rs
  • codex-rs/core/src/tools/code_mode/wait_handler.rs
  • codex-rs/core/src/tools/handlers/mcp_resource.rs

Codex already converts this into a FunctionCallOutput and gives the model another chance to continue, but weaker models often do not reliably self-repair after receiving the generic parse error. In practice this causes repeated malformed calls or turn failure instead of robust recovery.

What steps can reproduce the bug?

  1. Run Codex CLI on a task that requires multiple tool calls.
  2. Use a weaker / less reliable tool-calling model.
  3. Let the model produce a function call with a long string argument, nested JSON, or partially streamed JSON object.
  4. Observe that the model sometimes sends truncated JSON in arguments, for example a half-closed string or object.
  5. Codex logs an error like:
failed to parse function arguments: EOF while parsing a string at line ...
  1. The model receives the tool error, but may fail to re-emit a valid tool call and can get stuck or fail the turn.

Minimal malformed example shape:

{"cmd":"echo hello

What is the expected behavior?

Codex should recover more reliably from malformed tool-call JSON produced by weaker models.

At minimum:

  1. The parse error returned to the model should explicitly say that the JSON arguments were truncated and that the model must re-emit the full tool call with a complete JSON object.
  2. That guidance should be consistent across all function-tool argument parsers, not only some handlers.
  3. The error should make it obvious that this is a model-output/tool-arguments problem, not a router bug.

Additional information

Relevant code paths from the current source tree:

  • codex-rs/core/src/tools/handlers/mod.rs
  • codex-rs/core/src/tools/handlers/plan.rs
  • codex-rs/core/src/tools/code_mode/wait_handler.rs
  • codex-rs/core/src/tools/handlers/mcp_resource.rs
  • codex-rs/core/src/stream_events_utils.rs
  • codex-rs/core/src/tools/router.rs

Observed local source revision during analysis:

0ccd659b4

Suggested fix direction:

  • Keep the current behavior of returning a FunctionCallOutput back to the model.
  • Improve the returned error text for serde_json::Error in the EOF category so it explicitly instructs the model to resend the full JSON object.
  • Unify that behavior in the shared parser and the current parser bypasses listed above.
  • Avoid automatic JSON “repair” for shell/exec/apply-patch style tools, because silent repair of truncated arguments could mutate intent.

What steps can reproduce the bug?

x

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗