一、我为什么要提前备份聊天记录

      我之前一直使用第三方 API 访问 Codex。由于使用过程中可能更换账号、Provider 或登录环境,每次换号后,原来的聊天记录都可能无法继续显示,甚至在侧边栏中完全消失。

这次我准备改用官方账号。考虑到之前更换账号后聊天记录丢失的情况,我提前对当前 Codex 环境中的聊天数据进行了完整备份,希望在切换账号后仍然能够保留过去的工作记录、项目上下文和历史对话。

这次备份的目的主要有三个:

  1. 防止更换账号后聊天记录丢失。

  2. 保留过去项目中的讨论内容和解决方案。

  3. 在新账号和新环境下继续使用已有聊天,而不是从头开始。

二、恢复过程中遇到的问题

备份恢复并不是简单地把聊天文件复制回来,过程中出现了多个问题:

  • 聊天文件已经存在,但侧边栏中没有显示。

  • 项目节点能够显示,但项目下面显示“无任务”。

  • 部分聊天可以打开,但无法继续发送消息。

  • 旧聊天仍然指向之前使用的 Provider。

  • 旧 Provider 与当前官方账号环境不兼容。

  • 部分旧模型名称已经不能在当前环境使用。

  • 同一个工作目录对应了多个项目,导致聊天被分配到错误的项目节点。

  • Codex 运行期间会重新写入状态,导致刚恢复的侧边栏信息被覆盖。

这些问题说明,Codex 的聊天记录由聊天正文、任务数据库、侧边栏索引、项目映射和 Provider 配置等多个部分共同组成,必须整体恢复和调整。

本次恢复过程虽然遇到了一些问题,但最终保留了原有聊天记录,也验证了在官方账号环境下继续使用历史聊天的可行性。记录这套流程,是为了今后再次更换账号或恢复环境时可以快速参考,避免重复踩坑。
遇见同样问题的朋友可以把这篇文章直接发给codex看。


下面是一套可复用的 Codex 聊天备份与恢复流程。

一、先理解 Codex 数据由哪几部分组成

Codex 的聊天记录不是只由一个文件管理,而是由四部分共同组成:

  1. 聊天正文

    保存为 .jsonl 文件,位置通常是:

    C:\Users\<用户名>\.codex\sessions\

    每个聊天任务通常对应一个 JSONL 文件。

  2. 任务索引

    主要保存在:

    C:\Users\<用户名>\.codex\state_5.sqlite

    其中的 threads 表记录任务 ID、标题、模型、工作目录、时间等信息。

  3. 侧边栏目录

    主要保存在:

    C:\Users\<用户名>\.codex\sqlite\codex-dev.db

    其中的 local_thread_catalog 表决定哪些任务能在侧边栏显示。

  4. 项目归属和排序

    主要保存在:

    C:\Users\<用户名>\.codex\.codex-global-state.json

    其中包括:

    • 任务属于哪个项目
    • 项目下任务的排列顺序
    • 侧边栏项目状态

因此,只复制 .jsonl 文件,通常只能恢复聊天内容,不能保证任务出现在侧边栏。


二、备份时应保存什么

建议完整备份当前 .codex 目录,至少包括:

C:\Users\<用户名>\.codex\
├─ sessions\
├─ state_5.sqlite
├─ sqlite\codex-dev.db
├─ .codex-global-state.json
└─ config.toml

同时保留一份带日期的备份目录,例如:

D:\Codex备份\codex-20260730-170306\

备份时不要只保存聊天正文,还要保存数据库和配置文件。


三、恢复前的准备

1. 完全退出 Codex

必须关闭 Codex 主窗口,并确认相关进程已经退出。

否则 Codex 运行期间可能重新写入数据库或全局状态文件,导致刚恢复的侧边栏信息被覆盖。

2. 创建恢复前安全备份

在修改当前数据前,先复制:

C:\Users\<用户名>\.codex

例如:

D:\Codex备份\restore-safety\before-restore\

这样即使恢复结果不理想,也可以回滚。

3. 确认恢复范围

先明确:

  • 是否恢复归档任务
  • 是否恢复子任务
  • 是否覆盖当前已有聊天
  • 是否只添加缺失聊天

本次采用的是:

  • 不恢复归档任务
  • 不恢复子任务
  • 不覆盖现有记录
  • 只添加备份中当前环境缺失的记录

四、正确的恢复顺序

第一步:恢复聊天正文

比较备份目录和当前目录中的 .jsonl 文件。

只复制当前不存在的文件:

备份\sessions\...
→ 当前\.codex\sessions\...

不要直接覆盖同名文件。

本次恢复中,实际复制了缺失的 11 个 .jsonl 文件,没有覆盖已有文件。


第二步:恢复任务数据库

在:

state_5.sqlite

threads 表中补充缺失任务。

需要保持任务 ID 一致,并正确写入:

  • id
  • title
  • cwd
  • model
  • provider
  • created_at
  • updated_at
  • archived
  • 其他任务状态字段

如果只复制 JSONL,而没有补充 threads 表,聊天可能存在于磁盘上,但 Codex 不知道它存在。


第三步:恢复侧边栏索引

在:

sqlite\codex-dev.db

local_thread_catalog 表中补充或修复任务索引。

该表通常包含:

  • 任务 ID
  • 标题
  • 项目 ID
  • 工作目录
  • 模型
  • 提供商
  • 创建时间
  • 更新时间
  • 是否归档

这是解决“聊天文件存在,但侧边栏显示无任务”的关键步骤。


第四步:恢复项目归属

检查:

.codex-global-state.json

中的:

  • thread-project-assignments
  • sidebar-project-thread-orders

根据任务的工作目录,将任务匹配到对应项目。

例如:

D:\MyPythonProject\after-sale-agent-platform

应归入对应的项目节点,而不是只依靠标题判断。

需要注意同一个工作目录可能对应多个项目。如果存在重复项目,任务可能全部归到其中一个项目,另一个项目就会显示“无任务”。这类重复项目应先确认后再删除。


五、处理模型和 Provider 兼容性

这是恢复后最容易遇到的问题之一。

旧聊天可能记录了以前的 Provider,例如:

OpenAI
testvideo

或者旧模型,例如:

gpt-5.1-codex-max
gpt-5.3-codex
codex-auto-review

如果当前环境中没有对应 Provider,打开聊天时可能出现:

Model provider `OpenAI` not found

如果 Provider 存在但权限不足,可能出现:

401 Unauthorized
Missing scopes: api.responses.write

正确处理方式

如果用户已经不再使用旧 Provider,应将可继续使用的聊天迁移到当前环境支持的 Provider,例如:

provider: openai
model: gpt-5.5

需要同步检查并修改:

  • JSONL 聊天正文中的模型信息
  • state_5.sqlite 中的任务记录
  • codex-dev.db 中的侧边栏记录
  • config.toml 中的 Provider 配置

不能只改其中一个地方,否则可能出现:

  • 聊天能显示但打不开
  • 聊天能打开但无法继续
  • 侧边栏显示旧 Provider
  • 新消息仍然请求旧接口

本次恢复中,普通可见聊天已经迁移到当前环境的 openai Provider。归档任务和未恢复的子任务没有纳入处理。


六、恢复后的验证顺序

建议按以下顺序验证:

  1. 关闭并重新打开 Codex。
  2. 检查侧边栏项目是否显示。
  3. 展开项目,确认任务数量。
  4. 随机打开几条聊天。
  5. 检查历史内容是否完整。
  6. 在一条聊天中发送测试消息。
  7. 确认新消息能够正常执行。
  8. 检查是否仍出现 Provider、模型或权限错误。
  9. 检查是否有项目显示“无任务”。
  10. 检查是否存在重复项目或空项目。

最重要的是要测试“打开”和“继续发送”这两个环节。只显示历史内容,并不代表聊天已经完全恢复。


七、常见问题和原因

侧边栏显示项目,但项目下是“无任务”

通常不是聊天正文丢失,而是:

  • local_thread_catalog 缺少记录
  • thread-project-assignments 缺少映射
  • 项目工作目录不匹配
  • Codex 运行时覆盖了刚写入的全局状态

聊天能打开,但不能发送消息

通常是:

  • Provider 不存在
  • 模型已失效
  • API Key 权限不足
  • 缺少 api.responses.write 权限
  • 旧聊天仍指向旧 API 地址

同一项目出现两个目录

通常是两个项目节点使用了相同的工作目录,但名称不同。任务可能只被分配到了其中一个项目,另一个就会显示“无任务”。

重启后恢复内容又消失

通常是恢复时 Codex 仍在运行,运行中的程序重新保存了旧状态。应:

  1. 完全退出 Codex
  2. 再修改数据库和全局状态
  3. 修改完成后重新启动

八、推荐的安全恢复策略

最稳妥的顺序是:

备份当前 .codex
    ↓
比较备份与当前文件
    ↓
只复制缺失的 sessions 文件
    ↓
补充 state_5.sqlite 的 threads
    ↓
补充 codex-dev.db 的 local_thread_catalog
    ↓
恢复项目映射和排序
    ↓
统一 Provider 和模型
    ↓
退出状态写入程序
    ↓
重新启动 Codex
    ↓
打开并发送测试消息

可以把它概括为:

聊天正文负责“内容”,SQLite 负责“任务索引”,全局状态负责“项目显示”,配置和 Provider 负责“能否继续对话”。

这四部分必须同时正确,聊天才算真正恢复完成。

更多推荐