背景

最近我遇到一个很吓人的问题:Codex 桌面端里的项目聊天记录突然消失了。

现象是,在 Codex 左侧项目列表中,项目下面显示“没有聊天”。这些对话前一天还在,第二天打开软件后就不见了。因为前一天刚修改过 Codex 配置,所以第一反应是:是不是配置改坏了,导致历史记录被删了?

最后排查下来发现,聊天内容并没有丢,真正出问题的是 Codex 本地索引字段与当前版本不兼容。

现象

主要表现为:

  • Codex 项目目录仍然存在。

  • 项目本身可以被 Codex 识别,例如 Linux学习知识库app

  • 项目下的聊天列表显示为空。

  • 直接查看本地会话文件时,旧聊天记录仍然存在。

  • 重启电脑或重启 Codex 后,问题仍可能反复出现。

一开始还尝试过把旧任务置顶、修复全局状态文件,但这些方法都不稳定。

本地数据位置

Codex 的历史聊天主要涉及两个位置:

C:\Users\用户名\.codex\sessions
C:\Users\用户名\.codex\state_5.sqlite

其中:

  • sessions 目录保存实际对话内容,通常是 .jsonl 文件。

  • state_5.sqlite 是本地索引数据库,Codex 界面主要依赖它来决定哪些聊天显示在列表里。

所以,当界面里聊天消失时,不要第一时间认为记录被删除。更合理的排查顺序是先看 sessions 是否还在,再看 state_5.sqlite 里的索引是否异常。

误判方向

排查过程中先怀疑过几个方向:

  1. 聊天被归档了。

  2. 项目路径中的中文乱码导致匹配失败。

  3. .codex-global-state.json 里的项目映射被清空。

  4. 置顶状态丢失导致侧边栏不显示。

这些方向都解释了一部分现象,但不是最终根因。

比如 .codex-global-state.json 里确实出现过项目映射为空、置顶列表为空的问题,但即使手动写回,Codex 运行中的进程也可能把状态覆盖回去。而且修复置顶后,列表仍然不完整。

真正的关键线索来自对比“能显示的新聊天”和“不能显示的旧聊天”。

真正原因

旧聊天记录在 state_5.sqlitethreads 表里仍然存在,但很多旧记录的字段是:

model_provider = openai

而当前 Codex 版本中新创建的聊天记录使用的是:

model_provider = openai_http

这说明 Codex 升级或配置变更后,旧记录没有被完整迁移到新 provider 标识。当前版本的列表查询更倾向于识别 openai_http,于是旧聊天虽然还在数据库里,却被界面过滤掉了。

这就是为什么看起来像“聊天记录消失”,但实际内容还在。

修复思路

最终稳定生效的修复方式是:

  1. 备份 state_5.sqlite

  2. 找出真实用户创建的旧 Codex 任务。

  3. 将这些记录的 model_provideropenai 迁移为 openai_http

  4. 确认误归档的记录恢复为未归档。

  5. 重启 Codex,让界面重新读取数据库索引。

核心思路不是修改聊天内容,而是修复本地索引字段。

修复示例

下面是简化后的修复逻辑。实际执行前一定要先备份数据库。

(如果不懂,可以把这篇文章丢给codex,让它自己学自己解决)

import sqlite3
import shutil
import time
from pathlib import Path

db = Path(r"C:\Users\xie\.codex\state_5.sqlite")
backup = db.with_name(db.name + f".provider-migration-{time.strftime('%Y%m%d-%H%M%S')}.bak")
shutil.copy2(db, backup)

thread_ids = [
    "需要恢复的 thread id 1",
    "需要恢复的 thread id 2",
]

con = sqlite3.connect(db)
cur = con.cursor()

cur.executemany(
    """
    update threads
    set model_provider = 'openai_http',
        archived = 0,
        archived_at = null
    where id = ?
    """,
    [(thread_id,) for thread_id in thread_ids],
)

con.commit()
con.close()

执行后重启 Codex,旧聊天就会重新出现在列表里。

为什么重启后才生效

修复数据库时,Codex 仍然在运行。运行中的 Codex 会使用内存里的旧索引状态,不一定立刻重新读取 SQLite。

所以数据库修复完成后,需要完整退出并重新打开 Codex。重启后,Codex 重新读取 state_5.sqlite,旧记录才会重新显示。

经验总结

这次问题的本质是:

聊天内容没有丢,本地索引字段过旧,导致当前 Codex 版本不再展示旧记录。

以后如果再次遇到 Codex 聊天记录消失,可以按这个顺序排查:

  1. 检查 C:\Users\用户名\.codex\sessions 是否还有历史 .jsonl 文件。

  2. 检查 C:\Users\用户名\.codex\state_5.sqlitethreads 表是否还有旧记录。

  3. 对比能显示的新记录和不能显示的旧记录,重点看 model_providerarchivedcwdthread_source 等字段。

  4. 修改数据库前一定先备份。

  5. 修复后完整重启 Codex。

这次最终的关键修复点是:

model_provider: openai -> openai_http

修完后,旧聊天重新出现在 Codex 列表中,重启软件后也能正常读取。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐