You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG]: Delete session leaves data in database and on disk — race condition erases Deleted event before projector fires #30814
Clicking "delete session" in the UI does not always remove the session data from the database. The session row, messages, and related records can persist because of a race condition in the deletion pipeline.
Race condition: Deleted event is erased before projector processes it
Line 664 publishes a SessionV1.Event.Deleted event to the event store. Line 665 immediately calls events.remove(sessionID) which deletes ALL events for this session from both EventTable and EventSequenceTable (packages/core/src/event.ts:445-454).
The projector at packages/core/src/session/projector.ts:248-250 listens for Deleted events asynchronously:
If the projector has not processed the Deleted event before events.remove() deletes the event stream, the projector never fires. The session row and all cascade-related data remain in the database. No error is shown because the catch block at lines 666-668 silently swallows all exceptions.
Additionally, events.remove() is redundant — ON DELETE CASCADE from SessionTable (defined in packages/core/src/session/sql.ts) would clean up event rows automatically when the session row is deleted.
Note: Bugs 2-6 (tool output files, truncated output files, plan files, legacy storage, in-memory caches not cleaned up) overlap with existing issues #29694 and #16101. This issue focuses on the race condition only.
Suggested Fix
Remove the events.remove(sessionID) call at session.ts:665. The cascade delete from SessionTable already handles event cleanup. If the events.remove() is needed for a specific purpose, move it to the projector handler so it runs after the Deleted event is processed.
OpenCode version
main
Steps to reproduce
Create a new session and exchange several messages
Delete the session from the UI
Query the SQLite database: SELECT COUNT(*) FROM session WHERE id = '<session-id>'
The session row may still exist because the projector never received the Deleted event
The race condition in Bug 1 (events.remove() running before the projector processes the Deleted event) appears to be a new, distinct finding not covered by those issues.
synchronized event projectors run inline before events.publish(...) returns, so the session.deleted projector deletes the session row before events.remove(sessionID) runs
Activity
github-actions commentedon Jun 4, 2026
This issue might be a duplicate of existing issues. Please check:
The race condition in Bug 1 (
events.remove()running before the projector processes theDeletedevent) appears to be a new, distinct finding not covered by those issues.nexxeln commentedon Jun 5, 2026
synchronized event projectors run inline before
events.publish(...)returns, so thesession.deletedprojector deletes the session row beforeevents.remove(sessionID)runs