Codex CLI persists malformed tool_search_call arguments, causing 400 property_name_above_max_length on resume

Open 💬 7 comments Opened Jun 4, 2026 by volveezz

What version of Codex CLI is running?

0.137.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.5

What platform is your computer?

Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 unknown

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

WSL

What issue are you seeing?

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "[ObjectParam] [input[55].arguments.>'+ennialsf\u00f3lnub etsennialsreti\u05e2\u05e0\u05d8\u05e9apie \u0440\u044b\u0448iv\u00e9playerschuheNegotiishe \u0906\u092f\u094b\u091c
Tapelade\u0639\u062f\u064a\u0646ta\u00e7\u00e3onubwriter/cop HarrietenciamentobotsJuan meigeria rezSED\u0430\u043b\u0430\u043croch pencilsretipleados\u0434\u0435\u043d\u0438\u0435\u043c Nyereit Bots Bulk
Pantryasinoi\u00e3o.Generic_fillfinder\u043d\u0443\u0446\u044c Rasullaug\u043b\u0435\u0439_STAolfasetreit Streit Nou Dee Preston/legast\u00e1naFABj\u00e4nendenteJason Argentbots ETS opts th\u01b0\u1edfng
ballot frustratingnthestrian uncertainties eyeb Kerryhtarething\u6765\u770bbotAllocatornyamaWrite\u05dc\u05d9\u05eanub\u043f\u043b\u044f sach.zaxxer\u043f\u0430\u0440\u0430\u0442/be TachPur \u9999\u6e2fLaugh
konkurr el\u00e9trACLEolf globaleenant_ls\u10d5\u10d8\u10d3 setsreit leastelassen\u00fcssURITY \u0645\u0639\u0646gahretilish Ball\u2019abandil\u00f3st\u00e6Substring\u0941\u092anub \u0440\u0430\u0434\u0443
interferlanders\u0441\u0435\u043d\u0434\u0456 s\u00f8ger \u5927\u53d1\u5feb\u4e09\u5b98\u7f51 j\u00e9g\u00ebriszendstylesbotu cari hinkwaswo\u0443\u0441\u044b\u043b\u0430\u0440\u04b5\u04d9vidorsections/
Subthreshold\u0525\u0448\u044cdaawriteatillugu \u5927\u53d1\u5feb\u4e09\u5982\u4f55\u0445\u044b\u04b5
\u04bb\u04d9\u0440\u0431\u0438\u0439retry_Botsthroughoutfilebancookies\u04bf\u043a\u0430itaatspu\u0430\u04e1\u0430\u0440\u0430 Bruins\u5f69\u7968\u7f51\u5740pythonrit] [property_name_above_max_length] Invalid
property name in 'input[55].arguments': '>'+...rit' is too long. Expected a string with maximum length 256, but got a string with length 806 instead."
  },
  "status": 400
}

What steps can reproduce the bug?

Uploaded thread: 019e9232-51e7-7051-89ac-9fca142e3b3d

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

7 Comments

YitzhakMizrahi · 1 month ago

I hit the same failure class and was able to recover the affected session by editing the persisted rollout JSONL. Adding details in case they help narrow the bug.

Environment:

  • Current Codex CLI: 0.137.0
  • Affected session was originally created with Codex CLI: 0.130.0
  • The issue persisted after upgrading to 0.137.0, so upgrading alone did not repair the affected session.
  • Platform: Fedora Linux 44, kernel 7.0.9-205.fc44.x86_64
  • Terminal/multiplexer: tmux 3.6a
  • Model/provider: OpenAI, gpt-5.5

Observed behavior:

  • codex resume <thread-id> failed repeatedly with an API 400 shaped like:
[ObjectParam] [input[91].arguments.<garbage>] [property_name_above_max_length]
Invalid property name in 'input[91].arguments': ... is too long.
Expected a string with maximum length 256, but got a string with length 708 instead.
  • New Codex sessions worked normally; only the affected persisted session failed.

Local transcript diagnosis:

  • The affected rollout JSONL contained malformed records of type response_item / tool_search_call.
  • In those records, .payload.arguments was an object with a single garbage property key instead of the expected argument shape.
  • I found two malformed tool_search_call records in the same rollout file:
  • one oversized key length was 708
  • another oversized key length was 566
  • Each malformed tool_search_call was followed by a function_call_output with:
failed to parse tool_search arguments: missing field `query`

Recovery that worked:

  1. Backed up the rollout JSONL.
  2. Removed the malformed tool_search_call record.
  3. Removed its paired failed function_call_output record.
  4. Removed the adjacent token_count event for that failed tool call.
  5. Re-scanned the JSONL for any remaining .payload.arguments object keys longer than 256 chars.
  6. Found and removed a second malformed tool_search_call block the same way.
  7. After both malformed blocks were removed, the session resumed successfully.

The practical jq diagnostic I used was:

jq -r '
  select(.payload? and (.payload.arguments? | type)=="object") as $row
  | $row.payload.arguments
  | to_entries[]
  | select((.key|length) > 256)
  | [input_line_number, $row.timestamp, $row.type, ($row.payload.type // ""), ($row.payload.call_id // ""), (.key|length), (.key[0:80])]
  | @tsv
' ~/.codex/sessions/**/rollout-*.jsonl

Hypothesis:

Codex can persist malformed tool_search_call.payload.arguments after tool argument parsing fails. On resume, the persisted transcript is replayed into the API request, and the API rejects the oversized object key before the model can continue. The resume path probably needs to sanitize/drop invalid historical tool calls, or the persistence path should avoid writing malformed tool-call items after argument parsing fails.

menicPL · 1 month ago

I hit the same failure class in Codex Desktop, not just CLI resume.

Observed behavior:

  • Instead of a normal assistant reply, Codex surfaced the raw API error JSON directly in chat.
  • The error shape was:
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "[ObjectParam] [input[293].arguments....] [property_name_above_max_length] Invalid property name in 'input[293].arguments': ... Expected a string with maximum length 256, but got a string with length 1709 instead."
  },
  "status": 400
}

Notable details:

  • failing path: input[293].arguments
  • oversized property-name length: 1709
  • the garbage key contained long multilingual/random-looking text, similar to the malformed tool-call cases already described here
  • from the user's perspective this looked like Codex itself broke and dumped transport/backend error JSON into the conversation instead of recovering or showing a friendlier failure

This suggests the bug is broader than just a CLI resume edge-case:

  1. malformed tool-call/session state can still be constructed in Desktop
  2. the app may expose the backend validation error directly to the user instead of handling it as an internal failure

If helpful, I can add more reproduction context later, but I wanted to confirm this exact property_name_above_max_length pattern is also happening in Desktop with input[293].arguments.

ken-jo · 1 month ago

I hit the same failure class on Codex CLI and was able to narrow one occurrence down to the raw Responses websocket event, before rollout JSONL replay.

Environment:

  • Codex CLI: 0.139.0
  • Model: gpt-5.5
  • Platform: Linux 6.17.0-1016-oracle on aarch64
  • Originator in telemetry: codex-tui

What I observed:

  • The affected rollout had 40 tool_search_call response items.
  • 39 had the expected argument shape with query / limit.
  • 1 had malformed arguments:
{
  "type": "tool_search_call",
  "call_id": "call_0arIzewv9N3HEFLA8hQMNZ5o",
  "status": "completed",
  "execution": "client",
  "arguments": {
    "<redacted generated multilingual/gibberish key, 2503 chars / 2910 UTF-8 bytes>": []
  }
}

The immediately following rollout item was:

{
  "type": "function_call_output",
  "call_id": "",
  "output": "failed to parse tool_search arguments: missing field `query`"
}

Additional evidence from ~/.codex/logs_2.sqlite:

  • The malformed payload was already present in the raw websocket trace, not introduced by the JSONL writer.
  • Sequence:
  • 2026-06-16T09:04:39Z: stream disconnected - retrying sampling request (3/5 in 733ms)...
  • 2026-06-16T09:04:41Z: websocket reconnect succeeded for /responses
  • 2026-06-16T09:04:49Z: raw websocket event response.output_item.added for the same item/call id:
{
  "type": "response.output_item.added",
  "item": {
    "id": "tsc_0f0cd4c506096518016a3111b1dcb081989865875883ca83ab",
    "type": "tool_search_call",
    "status": "in_progress",
    "arguments": {},
    "call_id": "call_0arIzewv9N3HEFLA8hQMNZ5o",
    "execution": "client"
  },
  "sequence_number": 2
}
  • 2026-06-16T09:05:30Z: raw websocket event response.output_item.done for the same item/call id contained the malformed 2503-character property name in arguments.
  • The router then logged:
handle_output_item_done:build_tool_call: error=failed to parse tool_search arguments: missing field `query`

Code path that matches the transcript:

  • codex-rs/protocol/src/models.rs: ResponseItem::ToolSearchCall.arguments is a raw serde_json::Value.
  • codex-rs/core/src/tools/router.rs: ToolRouter::build_tool_call deserializes that value into SearchToolCallParams { query, limit }, which fails with missing field query.
  • codex-rs/core/src/stream_events_utils.rs: the FunctionCallError::RespondToModel path records a generic function_call_output with call_id: String::new().
  • After that, history normalization logs Tool search output is missing for call id: call_0arIzewv9N3HEFLA8hQMNZ5o and synthesizes an empty tool_search_output on later requests.

My current hypothesis:

  • The original malformed argument object is produced upstream of ToolRouter::build_tool_call because the completed Responses websocket item already contains it.
  • The client-side bug that makes this harder to recover from is that malformed client-executed tool_search_call parse failures are recorded as an orphan function_call_output with an empty call_id instead of a tool_search_output tied to the original call_id.
  • A robust fix likely needs two parts:
  1. server/model-side prevention of malformed tool_search_call.arguments, and
  2. client-side hardening so invalid tool_search_call items preserve call_id and do not poison persisted history/resume.

Potential client-side fix shape, if maintainers agree:

  • Add a regression test for a client tool_search_call with invalid arguments.
  • When parsing fails before a ToolCall is built, preserve the original call_id and record/respond with a tool_search_output such as tools: [] (or another structured error shape the Responses API accepts for tool_search) instead of function_call_output { call_id: "" }.
  • Consider a history normalization/resume guard that drops or repairs historical client tool_search_call items whose arguments are not shaped like SearchToolCallParams, to avoid later property_name_above_max_length replay failures.
ken-jo · 1 month ago

I have a small client-side hardening patch prepared for the second part above: it preserves the original tool_search_call.call_id and records a tool_search_output instead of an orphan function_call_output { call_id: "" } when client tool_search argument parsing fails.

The local patch is intentionally narrow:

  • 2 Rust files changed
  • regression test for malformed tool_search_call.arguments
  • git diff --check: pass
  • cargo fmt -- --config imports_granularity=Item --check: pass
  • just test -p codex-core handle_output_item_done_preserves_tool_search_call_id_for_invalid_arguments: pass

If this direction matches what the Codex team wants, would you be open to inviting an external PR for this focused client-side fix? I will hold off on opening a PR unless invited, per docs/contributing.md.

Necmttn · 29 days ago

Resume should validate persisted tool-call envelopes before replay. If a tool_search_call has malformed arguments, keep the original call id, attach a parse_error record, and emit a matching tool_search_output or repairable skip event. The session should never serialize an orphan output with an empty call id and then fail the whole resume request.

---

_Generated with ax._

RaresKeY · 23 days ago

I hit what looks like the same issue on Codex CLI 0.142.3 using gpt-5.5 with xhigh reasoning.

Sanitized sequence from local logs:

  1. A long CLI session triggered context compaction.
  2. After compaction, the session recorded a tool_search_call whose arguments object did not contain the required query field.
  3. Instead, arguments contained a single generated/gibberish multilingual property name with length 6585, value 173.
  4. The next transcript item recorded a failed tool parse with an empty call_id:
failed to parse tool_search arguments: missing field `query`
  1. On the next user turn, session replay sent the malformed item back in the request and the API rejected the whole turn:
invalid_request_error
[property_name_above_max_length]
Invalid property name in 'input[54].arguments': expected maximum length 256, got length 6585

I also saw normalization warnings consistent with poisoned replay state:

Tool search output is missing for call id: <redacted>
Orphan function call output for call id:

This was Codex CLI, not Desktop. Auth/websocket connection appeared healthy, and continuing in a fresh thread worked. The issue seems to be that an invalid internal tool_search_call can be persisted after compaction and then poisons future session replay.

TidyWeb · 11 days ago

For those still hitting tool-calling issues (namespace doubling, broken HTML rendering): before rolling back to 0.142.5, check whether your install is actually complete.

My symptoms matched what's being reported here, but the root cause turned out to be a missing platform binary — @openai/codex-linux-x64 — not a version regression. The global npm install -g had silently skipped the optional dependency, leaving an incomplete install regardless of version.

Fix (Linux x64):

npm install -g @openai/codex@0.143.0
cd ~/.nvm/versions/node/$(node -v)/lib/node_modules/@openai/codex
npm install --include=optional

That installs codex-linux-x64 into the correct nested location. Currently running 0.143.0 without issue — tool calls passing, HTML rendering correctly.