[BUG] Session registry file gets an extra trailing `}`, breaks JSON parsing

Status Open
Reported on v2.1.280
Maintainer reply None cached
Activity 1 comment · opened Sep 23, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

A native Claude Code interactive session's own registry file at ~/.claude/sessions/<pid>.json ended up with one stray extra } appended after an otherwise fully valid JSON object, making the file fail to parse with any standard JSON reader (json.loads in Python raises json.decoder.JSONDecodeError: Extra data: line 1 column 604 (char 603)). This was not a one-off/transient state: re-reading the file 5 times in a row, with no process writing to it during that window, produced the exact same parse failure every time — this is a persistent write-time bug, not a read-during-write race.

What Should Happen?

The session registry file should always be valid, parseable JSON — any code path that mutates it (e.g. adding the bridgeSessionId field) should never leave it in a state a standard JSON parser rejects.

Error Messages/Logs

json.decoder.JSONDecodeError: Extra data: line 1 column 604 (char 603)

Steps to Reproduce

I don't have deterministic repro steps for triggering the write itself (it happened during normal use of a long-running interactive session with Remote Control/bridge active), only the resulting corrupted artifact. Reporting the artifact since I can't reproduce the write path from the outside:

  1. Run a normal interactive claude session for a while with Remote Control / bridge enabled (session picks up a bridgeSessionId field at some point).
  2. Inspect ~/.claude/sessions/<pid>.json for that session.
  3. The file fails json.loads() / any strict JSON parser with "Extra data" at the very last byte.

Full file content (only the cwd path redacted, everything else verbatim):

{"pid":19231,"sessionId":"fe26da2d-7be2-40c3-bcf7-f7ae3aca1089","cwd":"/Users/<redacted>/projects/<redacted>","startedAt":1790123916284,"procStart":"Wed Sep 23 00:38:34 2026","version":"2.1.280","peerProtocol":1,"peerFeatures":["notify_idle","reply_across_default_dirs","artifact_yield"],"kind":"interactive","entrypoint":"cli","pidDomain":"darwin","messagingSocketPath":"/tmp/cc-socks/19231.sock","name":"ottoshare-factory-98","nameSource":"derived","nameSince":1790123916284,"updatedAt":1790171596104,"status":"idle","statusUpdatedAt":1790171596104,"bridgeSessionId":"session_018quXZnzXq4eb8dFN9MZfFR"}}

Note the very end: ...MZfFR"}}, two closing braces where the object only needs one. Every field before that point is well-formed, correctly typed, and in a sensible order, no truncation, no other corruption anywhere else in the file, just one extra } at the very end. The last field, bridgeSessionId, reads like it was added by a newer code path than the rest of the record. The shape of the corruption, one full, valid object with exactly one extra } tacked onto the very end, no other bytes disturbed, is consistent with a string-splice update (e.g. stripping the file's last }, appending ,"bridgeSessionId":"..."}) that in some code path fails to strip the original closing brace first, or that runs twice. This is a guess based on the artifact alone; the actual code path that writes this field isn't visible from the outside.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.280

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Impact: any external tool reading ~/.claude/sessions/<pid>.json with a standard JSON parser will silently fail to parse this file and can end up treating the session as if it doesn't exist — for us this meant the session disappeared from a local session-discovery tool's listing. We don't know whether Claude Code's own internals ever read this same file back and hit the same problem, flagging in case they do.

Suggested fix: whatever code path adds bridgeSessionId (or any other field) to an already-serialized session JSON file should do a full parse → mutate → re-serialize round trip instead of any string-level splice, so a malformed intermediate state is impossible by construction. Also worth checking whether the write to this file itself is atomic (temp file + rename), a previous non-atomic-write issue against a different registry file in this repo (#59811, "Registry file written non-atomically... session vanishes from picker") suggests this general pattern (partial or corrupted session registry writes) has happened here before.

(discovered via a small open-source local IPC tool, agent-peer, that reads this file)

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗