No conversation found with session ID:Claude Code 在告诉你什么
那个 id 的文件不在 claude --resume 找的地方,而出现这种情况的原因有五种
完整的消息就是一行:
$ claude --resume 7b1d2c3e-1111-4222-8333-444455556666 No conversation found with session ID: 7b1d2c3e-1111-4222-8333-444455556666
Claude Code 把每段对话存成一个文件 <session-id>.jsonl,放在 ~/.claude/projects 下按项目分的目录里。按 id 恢复就是找到那个文件。这个报错说的是它一个都没找到,或者找到的那个里面没有对话。它绝不意味着会话存在 Claude Code 忘了的地方:列表背后没有数据库,只有那些文件。
下面的内容都在 Claude Code 2.1.295 上用一个一次性的 CLAUDE_CONFIG_DIR 复现过。
它不是什么:目录不对
常见的建议是 cd 到会话当初跑的项目里。对按 id 恢复来说,在当前版本上这并不重要:查找会搜 ~/.claude/projects 下的每一个项目目录,测试里一个在某个仓库里开的会话,从另一个仓库按 id 恢复成功了。交互式选择器不一样,也就是不带 id 的 claude --resume:它列出你当前所在目录的会话,所以一个被改名或移动过的项目,它的会话不在列表里,但按 id 仍然有用。
五种原因
- 文件被清理了。
~/.claude/settings.json里的cleanupPeriodDays默认是 30 天,Claude Code 会删除比这更旧的转录,而且不说一声。上个月笔记里记下的一个 id,是撞上这个报错最常见的方式。清理是怎么工作的。 - 文件被删了。可能是手动删的,可能是
claude project purge,也可能是一个删掉旧.jsonl文件的清理脚本。 - 配置目录不一样。设置了
CLAUDE_CONFIG_DIR之后,Claude Code 读的是$CLAUDE_CONFIG_DIR/projects,完全不看~/.claude下的东西。一个 shell、一个容器或者一个 IDE 任务,如果它的设置和当初写会话的那个不同,那么来自另一套目录的每个 id 都会得到这个报错。 - 会话是 headless 写的。由 SDK 驱动的客户端和 headless 客户端写出的会话,可能落在
<config>/transcripts/而不是projects/。放在那里的文件--resume找不到;测试里它给出的正是这条消息,直到它被移到projects/下。 - 文件里没有对话。一个空的
.jsonl,或者只有一个摘要行、没有消息的,即使文件明明白白就在那里,也会给出同样的报错。
差一点的情况会打印别的东西:带 -p 时,短的 id 前缀会被拒绝,提示 --resume requires a valid session ID or session title,因为 claude -p --resume 要的是一个完整的 UUID 或者会话标题,不是前缀。
驱动 Claude Code 的程序,比如 Agent SDK 或者编辑器扩展,底层跑的是同一个 CLI,所以当这条消息作为一个更长报错的一部分出现时,原因和上面是同一套。
找到那个文件
# 它是不是在默认目录下的某处,包括 transcripts/
find ~/.claude -name '<session-id>.jsonl' -ls
# 这个 shell 用的是哪个配置目录
echo "${CLAUDE_CONFIG_DIR:-~/.claude}"
# 某个 id 在另一个文件里被提到,比如子智能体或改过名的副本
grep -rl '<session-id>' ~/.claude 2>/dev/null
如果 find 列出的文件大小是零,或者只有几百字节,那就是第 5 种,没什么可恢复的。如果它在 transcripts/ 下,就把它移进任意一个项目目录,然后按 id 恢复:
mv ~/.claude/transcripts/<session-id>.jsonl ~/.claude/projects/<project-dir>/ claude --resume <session-id>
如果它在另一个配置目录下,就用那个 CLAUDE_CONFIG_DIR 运行 claude --resume,或者把文件复制过去。如果 find 什么都没打印,文件就没了:在清理之前做的时间机器快照或其他快照,是 Claude Code 自己唯一还能用的副本。
让它别再发生
把保留期调长,清理就不会再拿走你还在引用的会话:
# ~/.claude/settings.json
{ "cleanupPeriodDays": 3650 }
这能解决第 1 种原因。对已经没了的会话没用,对其他几种也没用。
文件已经没了的时候
在文件还在时建好的索引,是那次清理之后唯一活下来的副本。deja 会读这台机器上每一个 Claude Code 转录,它读过的会话在 Claude Code 删掉文件之后仍然留在索引里。按内容找到它,再写回 claude --resume 会看的地方:
deja "the migration that broke the staging build" # 命中里带着会话 id deja show <id> # 读 deja 留下的那段对话 deja resume <id> --write-back # 写回 ~/.claude/projects,并打印恢复命令
写出来的文件里是对话,也就是用户和助手的来回;工具调用及其输出仍然只留在 deja 里。裸 deja 打开的界面里,Deleted 标签列出每一个被智能体删掉、而 deja 还留着的会话,对一个按 R 效果相同。对 deja 从没读过的会话,这些都帮不上忙,所以它得在清理发生之前就位:
curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh deja install --auto
第一次建索引会读取磁盘上已有的历史,所以它覆盖你现在手上的这些会话。建索引和检索都在本地。