Repository navigation
service: event seq collision drops session events after config reload #51798
Description
Summary
Editing opencode.jsonc while a session is actively running causes the service to lose session events. Two concurrent writers allocate the same event.seq for one session aggregate, and the second insert fails on UNIQUE(aggregate_id, seq). The affected turn is reported to the model as an error and the event is dropped, leaving the session unable to continue.
Environment
- opencode version: 2.0.18
- OS: Linux 6.18.33.2-microsoft-standard-WSL2 feat: compact and other improvements #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 (WSL2,
networkingMode=mirrored) - Terminal:
TERM=xterm-256color,TERM_PROGRAMunset,COLORTERMunset,WT_SESSIONset (Windows Terminal) - Shell:
/usr/bin/zsh - Install/channel: curl install,
latestchannel - Active plugins: none configured
Reproduction
- Start a session and let it run a tool call so the session has in-flight event writes.
- While that session is still running, edit the global config at
~/.config/opencode/opencode.jsonc(even a whitespace/comment-only edit). - The service watches
~/.config/opencodewith inotify and reloads configuration. - Within ~20 seconds, the running session's event write fails and the turn errors.
Observed twice in a single session:
2026-09-28T07:42:08.607 mtime of ~/.config/opencode/opencode.jsonc
2026-09-28T07:42:09.950 violation #1
2026-09-28T07:42:26.539 violation #2
Both failures are seq=427 on the same session aggregate, from two different event types — which is what makes this look like a sequence-allocation race rather than a duplicate insert:
params: evt_0e6f6d01b001iSAQxlXQDgakGK,ses_f191622cbffe670EoOV4COHAGu,427,message.part.updated.1
params: evt_0e6f710ea001N6MKHZveJfATKn,ses_f191622cbffe670EoOV4COHAGu,427,message.updated.1
Expected Behavior
A configuration reload should not interfere with in-flight session writes. Either the sequence allocator should serialize per aggregate so the second writer takes seq=428, or the insert should retry on conflict.
Actual Behavior
level=ERROR message=process error="Failed query: insert into \"event\" (\"id\", \"aggregate_id\", \"seq\", \"type\", \"data\") values (?, ?, ?, ?, ?)"
cause: EffectDrizzleQueryError ... (cause: SqlError ... SQLiteError: UNIQUE constraint failed: event.aggregate_id, event.seq)
The failure propagates into Session.updateMessage -> SessionProcessor.cleanup and is surfaced to the model as an UnknownError turn. The session stopped accepting prompts afterward.
Additional Context
- Reproduced 2 times, both within one session. I have not yet reproduced it from a clean start, so I cannot confirm the config edit is causal rather than coincidental with an unrelated write race — the reload and the collision are tightly correlated in both cases, but n=2 in a single session is weak evidence for causation.
- The service subscribes to the config directory, so this is reachable without any explicit action beyond editing a file:
level=INFO message="watcher subscribe" path=/home/xylar/.config/opencode type=directory ignores=3 role=server level=INFO message="watcher started" path=/home/xylar/.config/opencode type=directory backend=inotify ignores=3 role=server - Because sessions are event-sourced, a dropped event is not just a lost log line — it is a gap in the session's state history.
- No workaround found other than editing config only while no session is running. Restarting the service clears the stuck state.
- If a config edit legitimately needs to invalidate in-memory state, it would help to know whether that path is meant to be concurrency-safe.
Activity
github-actions commentedon Sep 28, 2026
This issue might be a duplicate of existing issues. Please check:
opencodejr commentedon Oct 28, 2026
Thanks for the detailed report and logs. I couldn't reproduce this on 2.0.18. A session was running a tool call that streamed output for about 15 seconds, and during that time I made 10 comment-only edits to the watched global
opencode.jsonc. Every session event was written in order, the turn finished normally, and the log had noUNIQUE constraint failederrors.Something in your logs suggests they may not have come from v2:
message.part.updated.1andmessage.updated.1, are v1 event names. In 2.0.18, session events are namedsession.*(for examplesession.tool.calledorsession.step.ended).Session.updateMessageandSessionProcessor.cleanupfrom the stack trace are v1 code. They don't exist in v2.So the failing process may have been a v1 install (
opencode-ai1.x) on the same machine. Could you check:opencode --version, and ofwhich -a opencode opencode2, from the shell where you start the session.opencode-aiinstalled alongside@opencode/cli.session.*event types), plus anything unusual in your setup, such as multiple clients attached to the same service.You can reply here, or edit the issue and leave a comment saying you've updated it.
opencodejr commentedon Oct 31, 2026
Closing this for now because we haven't heard back. I couldn't reproduce the
UNIQUE constraint failed: event.aggregate_id, event.seqerror on 2.0.18 by editing the config file while a session was running. Also, the event types and stack frames in your logs (message.part.updated.1,Session.updateMessage,SessionProcessor.cleanup) come from v1, not v2.If it happens again on 2.x, please reopen this issue or open a new one. Include the output of
opencode --versionandwhich -a opencode opencode2from the shell where you start the session, plus the v2 log lines (they mentionsession.*event types). Thanks for the detailed report.