Resume fails with Responses API 400 when persisted function_call.name contains NUL bytes

Open 💬 3 comments Opened May 24, 2026 by cratexnet

Summary

A Codex CLI session became impossible to resume because the persisted transcript contained a function_call.name with embedded NUL bytes. When Codex replayed that history to the Responses API, the API rejected the request with a 400 validation error.

Version

codex-cli 0.133.0

Error

{
  "error": {
    "message": "Invalid 'input[646].name': string does not match pattern. Expected a string that matches the pattern '^[a-zA-Z0-9_-]+$'.",
    "type": "invalid_request_error",
    "param": "input[646].name",
    "code": "invalid_value"
  }
}

Feedback / thread id

019e55fb-87ff-7a30-9d52-010b48f14964

Redacted session evidence

The persisted JSONL session contained a response item like this:

{
  "type": "response_item",
  "payload": {
    "type": "function_call",
    "name": "apply\\^@\\^@\\^@\\^@\\^@\\^@",
    "call_id": "call_EizYvzgC5R9tmVUJj17m5aDA"
  }
}

The same item's arguments also contained many \\^@ sequences, so this appears to be a corrupted persisted tool call, not only a legacy/namespaced tool name.

The following output item was also persisted:

unsupported call: apply\^@\^@\^@\^@\^@\^@

Manual recovery

I backed up the session JSONL and changed only that persisted function_call.name from:

apply\^@\^@\^@\^@\^@\^@

to:

apply_patch

After that, the session JSONL parsed successfully and no function_call.name values violated ^[a-zA-Z0-9_-]+$.

Related issues / prior work

This appears related to:

  • #6540
  • #10563
  • #9447

However, this case is slightly different from namespace normalization such as functions.exec_command: the stored transcript contains embedded NUL bytes and should be treated as corrupted history.

Expected behavior

Codex should not replay invalid historical function_call.name values to the Responses API.

Before sending replayed history or compaction payloads, Codex should validate historical function_call.name values and either:

  • sanitize control characters / invalid characters,
  • map known corrupted names to valid tool names when safe,
  • or drop/convert corrupted historical tool call items so one bad persisted item does not make the whole session impossible to resume.

Suggested regression test

A persisted history item with:

{
  "type": "function_call",
  "name": "apply\\^@\\^@",
  "call_id": "call_test",
  "arguments": "{}"
}

should not cause a Responses API request containing an invalid input[*].name.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗