Skip to content

OpenCode 2: raw message index stops advancing in a long session, so message search and ctx_expand fallback miss recent messages #772

Closed

Description

@null-axiom

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.

Activity

  1. magic-alfonso commented on Oct 23, 2026

    @magic-alfonso

    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.

  2. null-axiom commented on Oct 23, 2026

    @null-axiom
    Author

    Checked the other sessions on this install:

    • 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 no system 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.

  3. null-axiom commented on Oct 24, 2026

    @null-axiom
    Author

    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.

  4. magic-alfonso commented on Oct 25, 2026

    @magic-alfonso

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions