GPT5.4 is too aggressive to use parallel tool calls

Open 💬 6 comments Opened Mar 12, 2026 by winoros
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

0.114

What subscription do you have?

Pro

Which model were you using?

gpt-5.4

What platform is your computer?

Linux 6.17.0-14-generic x86_64 x86_64

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

ssh

What issue are you seeing?

While it also performs very aggressively parallel tool calls for my repo's specific command, it also does so for git operations.

When I say commit the changes, it could run git add and git commit in parallel and report an error git commit failed because it executed before the git add, then retry.

What steps can reproduce the bug?

Let it commit the diff produced in one session, which can also be produced with probability.

What is the expected behavior?

If the wrong parallel tool calling only affects our repo-specified commands, we can add note for it as repo-level guidance.

But the git operation may also be affected, so I think this is a model behavior issue.

Additional information

_No response_

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #13963

Powered by Codex Action

wbdb · 4 months ago

When it comes to unintended model behavior, it is best to use /feedback and post the ID here.

doublemover · 4 months ago

I've seen this too, it typically recovers gracefully but can spin out especially with parallel git commands, it then takes 10x longer doing them as sequential tool calls when a simple command1;command2 would suffice

winoros · 4 months ago
When it comes to unintended model behavior, it is best to use /feedback and post the ID here.

From my investigation, the behavior is aggressive enough to become a common issue.

winoros · 4 months ago

And yes, it's the same issue mentioned by the bot. I didn't find it when I created the issue.

Komzpa · 2 months ago

Bug: a single upstream response can contain duplicate tool calls with different item_id/call_id values but identical tool name and identical arguments. The client/executor currently treats those as independent calls, so the same side-effectful tool invocation can run more than once.

This is not just “the model is too aggressive with parallel calls”. The bug is visible in the protocol stream: exact duplicate tool calls are delivered in the same response with distinct IDs.

Actual behavior:

  • one response includes multiple tool calls with the same name and byte-identical arguments;
  • each duplicate has a different item_id and call_id;
  • the executor runs each one as a separate call.

Expected behavior:

  • every call_id still receives a valid tool output, because the Responses protocol expects that;
  • but identical tool-name + identical-arguments calls from the same response must not execute the side effect more than once.

Evidence from a local codex-lb archive sample: on 2026-05-03, grouping server_to_codex frames by (response_id, tool_name, sha256(arguments)) found 78 duplicate groups where the same response had multiple different item_id/call_id values for identical arguments.

Example 1:

response_id: resp_08992ca2b551600a0169f7b4043e208191a4472cbd2cbb1e95
tool: write_stdin
arguments: {"session_id":70670,"chars":"","yield_time_ms":1000,"max_output_tokens":16000}

item_id: fc_08992ca2b551600a0169f7b41959208191a5b07666455b4906
call_id: call_0KRpl3sU80a0u6ShtPAs31T6

item_id: fc_08992ca2b551600a0169f7b41959448191913256614e7f76eb
call_id: call_9NM99RA9KT8CaztXHEawp1dE

Example 2:

response_id: resp_048f292a0fec33a90169f7b506963481918637d3e2ca24012b
tool: write_stdin
arguments: {"session_id":5480,"chars":"","yield_time_ms":1000,"max_output_tokens":8000}

item_id: fc_048f292a0fec33a90169f7b514e824819192cf4fa211e34568
call_id: call_Izl3DvUhEZOoWVJTbj4k0OfE

item_id: fc_048f292a0fec33a90169f7b514e84081919343c6e748482228
call_id: call_iYVrQV6AoeVYEiBqi2YTYQDp

Example 3, same shape but with exec_command instead of polling:

response_id: resp_08992ca2b551600a0169f7b488451c8191a69cf7a9f0d6a296
tool: exec_command
arguments_sha256_prefix: e1f4ae7129da
arguments begin with: {"cmd":"python - <<'PY' > /tmp/pr169635_comments_after.json\nimport importlib.util, json\npath='/home/kom/.codex/plugins/cache/openai-curated/github/3c463363/skills/gh-address-comments/scripts/fetch_comments.py' ...","workdir":"/home/kom/proj/hass/core","yield_time_ms":1000,"max_output_tokens":30000}

item_id: fc_08992ca2b551600a0169f7b4a206dc8191a26a8c1e754573be
call_id: call_Al1WdQ1lxTNYcviknzAtdsoT

item_id: fc_08992ca2b551600a0169f7b4a207288191811872cfa8f2d3c1
call_id: call_yvvpFoyrK1vfxZCv6wWHAp5T

A robust executor fix is to treat exact same-response duplicates as one invocation: execute the first one once, then fan out/cache the resulting tool output for all duplicate call_ids, including duplicates observed after the first output has already completed.