Session resume fails when tool.execution_complete writes raw multiline content into events.jsonl
- Dominant language
- Shell
- Stars
- 11.2k
- Forks
- 1.9k
- Avg merge
- 14h 16m
- Merged PRs (30d)
- 6
Description
## Bug
Resuming a session can fail with:
```text
Failed to resume session: Error: Session file is corrupted
(line 1086: SyntaxError: Unterminated string in JSON at position 8038 (line 1 column 8039))
```
## Environment
- Copilot CLI version: 1.0.24
- OS: Linux
- Session ID affected: `46cb26fd-2fc9-4737-954a-1419bea933ff`
## Root cause
This was **not random file corruption**. The session's `events.jsonl` contained `tool.execution_complete` events that were written with **literal newline characters inside `result.content`**, so a single JSON object was split across multiple physical JSONL lines.
Two corrupted spans were present:
- lines `1086-1088`
- lines `1577-1579`
Both spans reconstructed cleanly into valid single `tool.execution_complete` events when the intermediate line breaks were replaced with escaped `\\n` and the combined string was parsed as JSON.
The affected events contained fetched page content beginning with:
- `Contents of https://www.anthropic.com/pricing:`
So the failure mode appears to be tied to persisted tool output that contains raw multiline content.
## Why this breaks resume
`events.jsonl` expects **one complete JSON object per line**. Once a writer emits literal newlines inside a JSON string value, the JSONL reader later tries to parse the first physical line as a complete JSON object and fails with `Unterminated string in JSON`.
## Evidence
The Copilot CLI log reported:
```text
Failed to parse session 46cb26fd-2fc9-4737-954a-1419bea933ff:
Failed to read JSONL from ~/.copilot/session-state/46cb26fd-2fc9-4737-954a-1419bea933ff/events.jsonl:
Invalid event at line 1086: SyntaxError: Unterminated string in JSON at position 8038
Event: {"type":"tool.execution_complete", ...}
```
External validation showed:
- line `1086` alone is invalid JSON
- line `1086 + "\\n" + 1087 + "\\n" + 1088` parses successfully as a single `tool.execution_complete` event
- same pattern for lines `1577-1579`
## Expected behavior
Session event writing should always escape embedded newlines inside string values so each event stays on one physical JSONL line.
## Suggested fix
1. **Fix on write**: ensure event serialization for `tool.execution_complete` always goes through normal JSON string escaping before appending to `events.jsonl`
2. **Defense on read**: consider a repair path for malformed JSONL where a line looks like the start of an event and subsequent lines can be safely rejoined
3. **Better error message**: include the event type and a hint that multiline tool output may have split a JSONL record
## Related issues
This looks related to the broader session-corruption family, but it appears distinct from the existing U+2028/U+2029 reports because the bad file here is caused by **raw literal newlines in tool output**, not line-separator Unicode characters.
Contributor guide
Assessment
This issue has not been assessed yet.