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
OpenCode 2: raw message index stops advancing in a long session, so message search and ctx_expand fallback miss recent messages #772
Update: the system-row correlation below is not the cause. The index is only written by the one-time store-generation rebase; the ongoing reconciler never runs on OpenCode 2 because it is gated on deps.client. See this comment.
Magic Context: 0.49.20 (observed since ~0.49.x in mid-October), OpenCode 2.1.4, macOS.
For a long OpenCode 2 session, the raw message index stopped advancing on Oct 10 (about two weeks ago), so message search and the ctx_expand archive fallback can't see recent messages.
message_history_index for the session: last_indexed_ordinal = 50446, last updated 2026-10-10 23:59 local. The session has ~56,600 ordinals, so ~6,000 recent messages are unindexed.
message_history_source also stops at 50446.
The stop is exactly where the first system-role row appears (ordinal 50445), around when the session moved to OpenCode 2. That's a correlation; I haven't confirmed the cause.
Practical effect: ctx_search's message lane ranks only pre-cutoff messages, so searches for recent work return old, loosely related hits (we've been seeing this), and the archive fallback for ctx_expand can't return recent raw text.
Related observation in the same session, cause not traced: 792 message tags (221 active) reference message IDs that don't exist in OpenCode's session_message (including __mc_whitespace_assistant_inert__ placeholders and old msg_000e… ids).
Expected: indexing continues past system rows (or whatever stalled it), and a stalled index is logged or surfaced rather than silently skipped. A way to re-run indexing for one session would also help.
Thanks, this is a clear and well-scoped report. Pinning the stop to the first system-role row (ordinal 50445), with both message_history_index and message_history_source ending there, gives us an exact place to start.
You're right that a stalled index should never be silent. Search quietly returning only older messages is worse than an error. We're in the middle of a larger internal change, so this is queued rather than started, and we'll post here when we pick it up. If you can say whether new OpenCode 2 sessions (ones that never ran on OpenCode 1) index past their own system rows, that will tell us whether it's the migration point or system rows in general.
A second long session migrated from OpenCode 1 shows the same stop: last_indexed_ordinal = 42810, and its first system-role row is at ordinal 42809. (The one in the report: 50446, first system row at 50445.)
A third migrated session that has nosystem rows is still indexing normally (1,075 of ~1,100 ordinals, updated on its last use).
There's no OpenCode 2-native session with system rows on this install, so I couldn't test that case directly.
So it points at system rows in general rather than the migration itself, though both stalled sessions are migrated ones and that isn't ruled out.
Correction to my earlier comment: system rows aren't the cause. On OpenCode 2 the index is only written by the one-time store-generation rebase (store-generation-rebase.ts → indexSourcesAfterOrdinal); after that nothing indexes new messages. The ongoing reconciler is only scheduled when deps.client !== undefined (hooks/magic-context/transform.ts:972), and the v2 adapter doesn't pass a client (v2/hooks/context.ts, createTransform), so it never runs; scheduleIncrementalIndex is only called from the v1 message.updated handler.
In all three sessions here, last_indexed_ordinal equals the session's raw-row count at its rebase time, including the session I'd called healthy: store-generation-rebase v1->v2 … index_rows_rebuilt=1075 at 2026-10-23 04:30, and 1,102 messages now. The system row only sat right before the stop point because OpenCode 2 writes its first instruction-update row minutes before the first Magic Context pass.
Likely fix: schedule reconciliation when the host reconciliation source (the v2 paged raw reader) is present, not only when client is, and re-run it when the store count passes last_indexed_ordinal (reconciliation is once per process today). reconcileSessionIndex already resumes from the watermark, so it would also backfill stalled sessions. Untested.
Shipped in 0.49.21. On OpenCode 2, the message index now keeps advancing as new messages arrive. Sessions that had stalled catch up from where they stopped, and a stall is logged once per session with its reason. The check for new messages runs off the turn. A committed revert also rebuilds that session's index, so reverted text no longer shows up in search.
We checked it on real OpenCode 2.0.22 and 2.1.0: search finds a message written after the point where indexing used to stop, and ctx_expand returns it. OpenCode 1 is unchanged. Thanks for tracing it to the system-role row, @null-axiom.
Activity
magic-alfonso commentedon Oct 23, 2026
Thanks, this is a clear and well-scoped report. Pinning the stop to the first
system-role row (ordinal 50445), with bothmessage_history_indexandmessage_history_sourceending there, gives us an exact place to start.You're right that a stalled index should never be silent. Search quietly returning only older messages is worse than an error. We're in the middle of a larger internal change, so this is queued rather than started, and we'll post here when we pick it up. If you can say whether new OpenCode 2 sessions (ones that never ran on OpenCode 1) index past their own
systemrows, that will tell us whether it's the migration point orsystemrows in general.null-axiom commentedon Oct 23, 2026
Checked the other sessions on this install:
last_indexed_ordinal = 42810, and its firstsystem-role row is at ordinal 42809. (The one in the report: 50446, firstsystemrow at 50445.)systemrows is still indexing normally (1,075 of ~1,100 ordinals, updated on its last use).systemrows on this install, so I couldn't test that case directly.So it points at
systemrows in general rather than the migration itself, though both stalled sessions are migrated ones and that isn't ruled out.null-axiom commentedon Oct 24, 2026
Correction to my earlier comment:
systemrows aren't the cause. On OpenCode 2 the index is only written by the one-time store-generation rebase (store-generation-rebase.ts→indexSourcesAfterOrdinal); after that nothing indexes new messages. The ongoing reconciler is only scheduled whendeps.client !== undefined(hooks/magic-context/transform.ts:972), and the v2 adapter doesn't pass a client (v2/hooks/context.ts,createTransform), so it never runs;scheduleIncrementalIndexis only called from the v1message.updatedhandler.In all three sessions here,
last_indexed_ordinalequals the session's raw-row count at its rebase time, including the session I'd called healthy:store-generation-rebase v1->v2 … index_rows_rebuilt=1075at 2026-10-23 04:30, and 1,102 messages now. Thesystemrow only sat right before the stop point because OpenCode 2 writes its first instruction-update row minutes before the first Magic Context pass.Likely fix: schedule reconciliation when the host reconciliation source (the v2 paged raw reader) is present, not only when
clientis, and re-run it when the store count passeslast_indexed_ordinal(reconciliation is once per process today).reconcileSessionIndexalready resumes from the watermark, so it would also backfill stalled sessions. Untested.magic-alfonso commentedon Oct 25, 2026
Shipped in 0.49.21. On OpenCode 2, the message index now keeps advancing as new messages arrive. Sessions that had stalled catch up from where they stopped, and a stall is logged once per session with its reason. The check for new messages runs off the turn. A committed revert also rebuilds that session's index, so reverted text no longer shows up in search.
We checked it on real OpenCode 2.0.22 and 2.1.0: search finds a message written after the point where indexing used to stop, and
ctx_expandreturns it. OpenCode 1 is unchanged. Thanks for tracing it to the system-role row, @null-axiom.