Repository navigation
Description
OpenCode Desktop 1.18.12: sessions spanning the 2026-08-14 message-ID wrap stop accepting messages (agent loop exits at step=0)
Environment: Windows 11 · OpenCode Desktop 1.18.12 (embedded sidecar server) · SQLite storage.
Symptom
Since 2026-08-14T11:19:55Z, sessions whose last assistant message was created before that moment can no longer receive messages:
- Sending a message writes the user text to the DB, but the agent loop exits immediately (
loop ... step=0→exiting loopin the log) and never calls the LLM — the conversation "ends" instantly with no reply. - After reloading the session, the sent message appears out of order / missing, because the UI renders messages sorted by ID.
- New sessions created after the wrap work normally, which made it look like a single broken conversation.
Root cause (问题原因)
Message/part IDs are generated by the ascending() helper:
const current = BigInt(timestamp) * 0x1000n + BigInt(counter);
// ID = 48-bit hex of (timestamp << 12 | counter) + 14 random base62 charsThe embedded time field is only 36 bits: Date.now() mod 2^36, which wraps every 2^36 ms ≈ 2.18 years. The wrap occurred at Date.now() = 26 × 2^36 = 1,786,706,395,136 ms = 2026-08-14T11:19:55Z:
- IDs generated just before the wrap start with
msg_ffff...(high lexicographic value) - IDs generated just after the wrap start with
msg_0001...(low value)
In the run loop the "nothing to do" check is roughly:
if (lastAssistant?.finish && !["tool-calls"].includes(lastAssistant.finish) && !hasPendingToolCalls
&& lastUser.id < lastAssistant.id) { log("exiting loop"); break; }For an affected session, the pre-wrap assistant message (msg_ffff...) sorts after the freshly sent user message (msg_0001...), so lastUser.id < lastAssistant.id evaluates true and the loop concludes the newest message was already answered — it never runs.
Reproduction
- In a session, exchange at least one assistant reply before
2026-08-14T11:19:55Z. - After that time, send a new message in that same session.
- Observed: the message row is persisted, the loop logs
step=0thenexiting loop, no assistant reply is produced, and the rendered order is broken after refresh.
This affects (a) sessions with messages on both sides of the wrap, and (b) sessions whose last message is a pre-wrap assistant reply when the user sends after the wrap. Any long-lived session will hit it again at the next wrap.
Workaround applied (解决办法)
Because restarting/updating cannot fix the stored ordering, I rewrote the affected sessions' message/part IDs in SQLite to a monotonic scheme (backup taken via VACUUM INTO first, IDs regenerated in time_created order, parentID/JSON references and event data remapped, foreign keys verified). After that, the loop proceeds normally again.
Suggested fix
- Stop encoding the time modulo 2^36 — use a full-width timestamp (or a wider ID), so IDs stay monotonic across the wrap boundary; and/or
- Make the loop-completion check and UI ordering compare
time_created(with ID only as a tiebreaker) instead of lexicographic ID order.
This issue was automatically created by an AI assistant on behalf of a user (auto-generated report: root cause analysis, workaround, and suggested fix were compiled by the assistant; reproduction steps verified against the local database).
Activity
github-actions commentedon Aug 14, 2026
This issue does not fully meet our contributing guidelines.
What needs to be fixed:
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
This issue might be a duplicate of existing issues. Please check:
lastUser.id < lastAssistant.idcheck in the run loop breaking when IDs are not monotonically ordered)runLoopID-comparison bug and suggests the same fixes (compare bytime.createdinstead)If you believe this was flagged incorrectly, please let a maintainer know.
11inyuan commentedon Aug 14, 2026
Closing as duplicate of #38787 — same root cause: the runLoop's lexicographic lastUser.id < lastAssistant.id comparison breaks when message IDs are not monotonic. The wrap-around case (2026-08-14, IDs flipping order) is added as a comment on #38787.