Session resume crashes on Edit tool_use with replace_all: true and empty new_string

Resolved 💬 3 comments Opened Mar 29, 2026 by spm1001 Closed Apr 17, 2026

Bug

Resuming a session crashes immediately if the conversation contains an Edit tool call with replace_all: true and new_string: "". The session ran fine originally — the crash only happens on --resume.

ERROR  undefined is not an object (evaluating 'q.startsWith')
/$bunfs/root/src/entrypoints/cli.js:1770:487

- eA7 (/$bunfs/root/src/entrypoints/cli.js:1770:487)
- Ze7 (/$bunfs/root/src/entrypoints/cli.js:2927:18047)
- qJ (/$bunfs/root/src/entrypoints/cli.js:452:20997)
- OY (/$bunfs/root/src/entrypoints/cli.js:452:39538)
- _s (/$bunfs/root/src/entrypoints/cli.js:452:50229)
- aE8 (/$bunfs/root/src/entrypoints/cli.js:452:86903)
- fG (/$bunfs/root/src/entrypoints/cli.js:452:85865)
- oE8 (/$bunfs/root/src/entrypoints/cli.js:452:85687)
- PX8 (/$bunfs/root/src/entrypoints/cli.js:452:82433)
- d8 (/$bunfs/root/src/entrypoints/cli.js:452:6488)

Reproduction

  1. Start a session and make several Edit tool calls (these will work fine on resume)
  2. Make one Edit with replace_all: true and new_string: "" — i.e. deleting all occurrences of a string rather than replacing them
  3. Exit the session normally
  4. claude --resume <session-id> — crashes before rendering

In my case the Edit was removing a path prefix from a plan document:

old_string: '~/Repos/batterie/tafelmusik/'
new_string: ''
replace_all: true

The session had ~30 other Edit calls that all resume fine. Only this combination crashes.

What I found

I binary-searched the 244-line JSONL to isolate the exact entry. Removing the single Edit tool_use line (and its tool_result) from the JSONL + repairing the parentUuid chain allowed the session to resume with full history.

The crash is in eA7, which is assigned as renderToolResultMessage for the Edit tool. It destructures {filePath: q} from its argument and immediately calls q.startsWith() with no null guard. The object it receives has filePath: undefined.

Stripping toolUseResult from the JSONL entry didn't help — the renderer appears to reconstruct it from the tool_use input, and the reconstruction produces an object missing filePath.

Not a duplicate of existing session resume issues

This is not a parentUuid chain break (#37437, #35024, #33651), not a 400/streaming error (#39818, #40316), not a blank session load (#28577, #40319), and not a message ordering problem (#31330). Those are all about conversation data integrity. This is a renderer crash on a specific Edit input shape — the JSONL data is perfectly valid.

Environment

  • claude --version: 2.1.86
  • OS: Debian 13 (trixie), Linux 6.12.74 aarch64
  • Shell: bash
  • Hardware: Hetzner cloud (CAX21)

Suggested fix

Null guard in eA7 before q.startsWith(), matching the pattern already used in tA7:

// tA7 already does this correctly:
function tA7({file_path:q},{verbose:_}){
  if(!q)return null;  // ← guard
  if(q.startsWith(MH()))return"";
  ...
}

// eA7 is missing the guard:
function eA7({filePath:q,structuredPatch:_,originalFile:K},O,{style:z,verbose:Y}){
  // needs: if(!q)return null;
  let H=q.startsWith(MH());  // ← crashes when filePath is undefined
  ...
}

View original on GitHub ↗

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