/insights aborts with "TypeError: null is not an object (evaluating E.startsWith)" when a session has a tool_use block with "name": null
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
/insights aborts with a JavaScript exception and produces no report:
TypeError: null is not an object (evaluating 'E.startsWith')
It happens whenever any session transcript under ~/.claude/projects contains an assistant tool_use block with "name": null. /insights scans all projects (not just the current working directory), so a single malformed tool_use block anywhere aborts the entire report, even when the cwd's own transcripts are clean.
Root cause
The insights session parser iterates the assistant tool_use blocks and guards only on key presence, then calls .startsWith() on the value:
if (S.type === "tool_use" && "name" in S) {
let E = S.name;
// ...
if (E.startsWith("mcp__")) L = !0; // throws when E === null
"name" in S is true when the value is null, so E.startsWith throws. There is no try/catch around this loop, so the whole report aborts. (Compare #90935: same class of defect — guarded undefined but not null, then .startsWith.)
Reproduction
- Ensure a transcript line exists with a tool_use block whose
nameis explicitlynull, e.g.:
{"type":"assistant","message":{"content":[{"type":"tool_use","id":null,"name":null,"input":{}}]}}
- Run
/insights. - Observe
TypeError: null is not an object (evaluating 'E.startsWith')and no report.
In the reporter's local data: 416 .jsonl files, 12,145 tool_use blocks, 7 with a non-string name (null), across several projects. The offending blocks carry MCP-style args in input (e.g. judgment_id/relation), suggesting an MCP tool call was persisted without name/id — a possible secondary transcript bug.
Expected
/insights should skip/ignore tool_use blocks with a missing or null name (or coerce to a string) instead of aborting the whole report.
Workaround
Normalize the offending entries ("name": null → a string) in the affected transcripts, with a backup. This unblocks /insights but is a local edit to session history.
Environment
- Claude Code: 2.1.299 (latest at time of writing)
- OS: macOS (Darwin 27.0.0)
- Terminal CLI (native install)
---
_Reproduced and root-caused locally against the published 2.1.296 and 2.1.299 bundles._