-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
Summary
Large legacy message.summary.diffs[*].before/after payloads can make a non-empty session render as a blank history view after restart/reopen.
I hit this with a local session that still had:
660messages3344partsrunning tool parts = 0- latest completed message around
2026-03-15 15:40:58
but the desktop app reopened the session as an empty timeline.
Evidence
- The affected session was not empty in SQLite.
8user messages embedded oversizedsummary.diffs[*].before/afterpayloads.- The largest single
message.datarow was about79,009,021bytes. - Total
message.datafor the session was about345 MB. - The oversized summaries included
.agent-history/EVENTS.jsonl/MANIFEST.json.
Root Cause
Snapshot.diffFull() currently returns full file contents in FileDiff.before/after, and those diffs are persisted into two places:
session_diffstorage viaSessionSummary.summarizeSession()user.summary.diffsviaSessionSummary.summarizeMessage()
That means a large text file diff can be written directly into message.data. When an old session is reopened, Session.messages() / MessageV2.page() hydrates those oversized rows and the renderer ends up trying to load a giant history payload just to render the timeline.
Expected
One oversized diff should not make a session unreadable. Session history should still open, and diff metadata should degrade safely.
Actual
The session title loads, but the timeline can come back blank after restart/reopen even though the session data is still present.
Proposed Fix
Two-layer fix:
-
Write-side protection
- bound inline
FileDiff.before/afterpayloads - keep
file,status,additions,deletions - record
before_bytes,after_bytes,trimmed: true - clear inline contents when the payload is oversized
- bound inline
-
Read-side protection
- sanitize legacy oversized
summary.diffson read so old sessions become readable again without manual DB cleanup
- sanitize legacy oversized
I have a patch for this and can open a PR immediately.