anomalyco / anomalyco/opencode
消息 ID 生成回绕导致旧会话静默拒收新消息(1.17.4,Linux)
Open
@kitlangton is already working on this.
Since Aug 17, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
升级后(约 8/14 19:22 起),所有「创建于升级前、升级后又继续使用过」的会话都无法继续对话:发送新消息后没有任何反应,换模型、重开会话都无效,服务端日志只有 loop step=0 后立即 exiting loop,新消息从未被处理。不报错、不产生回复,属于静默失败。
环境
- opencode 1.17.4(Linux / WSL)
- 消息/会话存储在 SQLite(~/.local/share/opencode/opencode.db)
根因
SessionPrompt.run 的 agent 循环依赖消息 ID 的字典序来挑选"最新消息": - latest() 通过 J.id > maxId 选取最新 user / 最新 assistant(按 ID 字典序,而非时间);
- 循环开头存在退出分支:当"ID 最大的 assistant 已 finish、且其 ID 大于 ID 最大的 user"时,判定为"对话已完成"直接 exiting loop。
问题在于消息 ID 生成器存在回绕:升级前生成的 ID 前缀为 fffb...~ffff...,升级后生成的 ID 前缀为 0000.../00d...。由于 'f' > '0',旧消息的 ID 字典序反而大于新消息。于是: - 会话中同时存在新旧消息时,latest() 把旧(8/14 之前的)assistant 当成"最新",其 finish 已就绪且 ID 大于任何新用户消息 → 循环认为对话已完成 → 退出;
- 再次发送新消息时重复同样过程,新消息永远得不到回复。
症状与"8/14 19:22 之后发的消息从没人回复"完全吻合(该时间点前后会话里出现了成批的未应答用户消息)。
影响范围
任何同时包含回绕前后消息的会话都会中招。我库中检测到 4 个(最大一个 1 万多条消息),其中两个主工作会话自 8/14 19:22 起即静默失效,直到今天全库排查才发现。
复现步骤
- 在旧版本中创建会话并产生若干消息(ID 为 ff... 前缀);
- 升级到 1.17.4;
- 在该会话中发送新消息;
- 观察:消息写入 DB,但服务端日志仅 loop step=0 → exiting loop,无回复。
期望行为
消息的"最新"判断应基于时间(time_created)或使用可排序 ID,保证新消息一定被处理。
可行的修复方向
- latest() / 退出判断改按时间而非 ID 字典序;
- 修复 ID 生成器的回绕,保证 ID 字典序与时间序一致。
本地已执行的临时补救(供参考)
对受影响会话的所有消息按时间重排了消息 ID(同步改写 parentID、part.message_id、part.data.messageID、compaction 的 tail_start_id),已确认会话可恢复正常对话。但这只能自救当前库,建议官方修复并考虑提供迁移工具。
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.