Skip to content

[Bug]: 自动历史修复误删新版任务侧边栏目录(附单线程应急恢复方法) #2242

Description

@Yuimi-chaya

进展更新:本地补丁已通过真人验收

2026 年 9 月 19 日,测试修复后的本地构建后确认:几个项目中,我还有印象的线程都回来了。

修复已提交为 PR #2243。这是多个项目中能够确认的任务恢复结果,不代表已逐一核验全部历史、全部无归属任务或长期重复启动场景。PR 提交及本地验收通过不等于上游已合并或发布修复版;在使用仍含旧逻辑的版本时,下面的提醒和应急方法仍适用。

提醒与影响范围

开启“启动前自动修复历史会话”的用户请留意:部分新版任务可能从 Codex 侧边栏消失,但仍能在 Codex++ 管理器中找到,而且并未归档。不要因此直接删除数据库、清空索引或反复运行旧版修复。

本报告针对“历史还在,但侧边栏目录项被删除”的情况,不代表所有任务消失、历史回滚或 no rollout found 都是同一个原因。

单线程应急恢复方法

可以在一个新任务中,让 Codex 列出消失任务的名字并读取它,然后手动点击新任务里的读取结果入口,进入原任务。

  1. 新建一个任务,提供消失任务的名称;记不清全名时,可提供项目名和关键词,让 Codex 先查找并列出候选名称。
  2. 确认目标后,让 Codex 调用任务读取工具(read_thread)读取那个任务,生成读取结果入口。
  3. 点击新任务中该读取结果对应的任务链接,进入原任务,再检查侧边栏。

可直接使用这样的请求,替换其中的示例名称:

请查找名字包含“旧项目代码审查”的历史任务,先列出候选任务名称。确认目标后,请调用任务读取工具读取它,让我能点击读取结果里的入口进入原任务。不要新建同名副本,不要改归档状态、项目归属或数据库,也不要自动批量打开任务;工具不可用时请明确说明,不要编造链接。

我已在一个受影响任务上实际验证:从新任务的读取结果入口点进去后,原任务重新出现在侧边栏。

注意:

  • 仅让模型输出名字或普通文字,不等于调用了任务读取工具;需要点击实际读取结果里的原任务入口。
  • 这属于单线程应急方法,不是全量恢复,也不能保证所有消失任务都适用。
  • 点击进入会触发 Codex 的读取/恢复流程,可能更新活跃时间、工作目录的路径表示或任务设置,不是完全零写入操作。
  • 旧版自动历史修复若再次执行,恢复的目录项仍可能被删除。排查期间可暂时关闭“启动前自动修复历史会话”,不要把反复修复或重启当作恢复办法。
  • 如果任务实际历史已丢失、读取报 no rollout found,此方法不能代替数据备份恢复。

当前行为

  • 有的项目全部任务入口消失,有的项目只剩部分任务。
  • Codex++ 管理器仍能看到受影响任务,任务不是归档状态。
  • 还怀疑部分无归属任务入口也缺失,但尚未逐一确认,不能据此推断全部无归属任务都受影响。
  • 已检查的样本在 state_5.sqlite 和 rollout 中仍有历史,session_index.jsonl 也保留对应记录,但侧边栏使用的 sqlite/codex-dev.db 中缺少对应 local_thread_catalog 行。

预期:历史同步不应删除有效、未归档的用户任务目录项;符合当前列表规则且历史仍在的缺失目录项应能补回。

环境与复现

  • 系统:Windows x64。
  • Codex Desktop:26.915.4065.0
  • Codex++:1.3.0 本地构建;同时在 2026 年 9 月 19 日核实的上游 main b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6 上复现了以下代码问题。
  • 受影响样本的供应商为 custom,与当前配置一致;开启了“启动前自动修复历史会话”。并不需要先切换供应商才能触发。

隔离测试的最小条件:

  1. 准备新版 threads schema,用户任务满足 archived = 0、非空 previewhistory_mode = 'paginated',但旧字段 has_user_event = 0;rollout 存在且包含用户消息。
  2. local_thread_catalog 中保留其中一项,并让另一项缺失。
  3. 在供应商不变的情况下运行上游的 provider sync。
  4. 结果:已有的有效目录项被删除,缺失项也没有补回。

请勿在真实历史数据库上手动构造上述条件。 复现已使用临时数据完成;排查或尝试修复前,应完整退出相关进程,离线备份历史文件、数据库及其 WAL、项目归属状态。

已定位的代码问题

crates/codex-plus-data/src/provider_sync.rs

  • collect_catalog_repair_plan 使用 has_user_event == 1 判断目录修复资格。
  • repair_missing_local_thread_catalog_rows_filtered 在全量修复中删除不符合资格的目录项。
  • 新版分页历史可能已有真实用户消息和非空 preview,但旧 has_user_event 仍为 0。把该旧标记当成强制条件,会误删这类任务的侧边栏目录项。

这不是“Codex 的任务列表直接按旧标记过滤”。直接打开后恢复的样本仍然保持 has_user_event = 0,却重新进入了目录并显示出来。

本地同步前备份也支持这个方向:2026 年 9 月 18 日的备份中保留四个样本目录项,之后的备份只剩原本仍可见的一项;手动进入其中一个消失任务后,其目录项重新出现。备份不能单独证明每次删除的精确执行时刻,但上面的删除行为已通过修复前失败测试独立复现。

修复进展

本地补丁已改为:具有 preview 字段时按非空预览判断资格,只有旧 schema 才回退到旧标记;保留归档、子代理、agent role、来源和 rollout 存在性等保护,不通过全量设置 has_user_event = 1 或改写工作目录来掩盖问题。

本地验证:provider-sync 56 项通过,Rust 工作区 1422 通过 / 0 失败 / 3 忽略,前端 234 项通过,Windows 编译打包通过。

本地补丁已通过上述范围的真人验收,并已提交 PR #2243 PR 使用与验收构建相同的 9552597,验收后没有追加源码修改。上游正式修复的合并和发布状态请以 PR 及后续发行说明为准;本报告继续保留应急方法和风险提醒。

相似表现可参考 #1359#1948no rollout found#2205 的历史回滚与本报告尚未证明同因,请不要混为一谈。

提交前确认

  • 未附带 API Key、Token、账号、真实任务名称、任务内容或个人路径。
  • 已在上述上游提交的隔离测试中复现代码问题。
  • 本地修复已完成真人恢复验收:几个项目中仍有印象的任务已恢复,范围限制见顶部更新。

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions