codex - 💡(How to fix) Fix tool calls sometimes fail because the model emits truncated JSON in `function_call.arguments` [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#19765Fetched 2026-04-28 06:37:34
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×4unlabeled ×2

Error Message

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 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. 5. Codex logs an error like: 6. The model receives the tool error, but may fail to re-emit a valid tool call and can get stuck or fail the turn.

  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. The error should make it obvious that this is a model-output/tool-arguments problem, not a router bug.
  • 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.

Root Cause

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

Fix Action

Fix / Workaround

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:

  • 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.

Code Example

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

---

failed to parse function arguments: EOF while parsing a string at line ...

---

{"cmd":"echo hello
RAW_BUFFERClick to expand / collapse

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

extent analysis

TL;DR

Improve the error handling for truncated JSON in function_call.arguments by returning a more informative error message that instructs the model to resend the full JSON object.

Guidance

  • Identify the locations where serde_json::from_str(arguments) is used, such as in codex-rs/core/src/tools/handlers/mod.rs and other listed handler files, to unify the error handling behavior.
  • Modify the error handling for serde_json::Error in the EOF category to return a more informative error message that explicitly instructs the model to resend the full JSON object.
  • Ensure that the improved error handling is consistent across all function-tool argument parsers to prevent confusion and improve model recovery.
  • Review the code in codex-rs/core/src/stream_events_utils.rs and codex-rs/core/src/tools/router.rs to ensure that the error handling is properly propagated and logged.

Example

// Example of improved error handling for serde_json::Error
match serde_json::from_str(arguments) {
    Ok(json) => {
        // Process the JSON object
    }
    Err(err) => {
        if err.is_eof() {
            // Return an error message that instructs the model to resend the full JSON object
            return Err("Error: Truncated JSON arguments. Please resend the full JSON object.".into());
        } else {
            // Handle other error cases
        }
    }
}

Notes

The suggested fix direction is to improve the error handling for truncated JSON in function_call.arguments without attempting to automatically repair the JSON. This approach prioritizes the model's ability to recover from errors and ensures that the intent of the tool call is not mutated.

Recommendation

Apply the workaround by improving the error handling for truncated JSON in function_call.arguments to return a more informative error message that instructs the model to resend the full JSON object. This approach is preferred because it

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix tool calls sometimes fail because the model emits truncated JSON in `function_call.arguments` [1 participants]