
把 Claude Code 接入 openclaw 之后最让人血压上来的一个报错就是你终端里跑claude明明一切正常会话、上下文、工具调用都没毛病可一到 openclaw 的调度链路里它就冷冷地给你一句“claude code 未登录”。先在群里问了圈发现栽在这上面的人还真不少。先说结论这个“未登录”提示绝大多数情况下不是你的 Anthropic 账号真的掉了线而是 openclaw 在拉起本机 Claude Code 子进程的时候没能读到你的登录凭证。凭证文件还躺在那里但你授权的那把“钥匙”它看不见、摸不着于是它只能如实向你汇报这家伙没登录。这篇文章我会按真实排障的顺序把这个“假未登录”的判定机制、凭证存储方式、完整排查链路、不同部署方式下的修复方案以及怎么让它以后别再来烦你一次讲清楚。你在 openclaw 里调用 Claude Code 遇到同样问题的话直接照着做就行如果你正打算这么配也可以提前把坑绕开。1. openclaw 判定“未登录”的机制拆开看它到底在查什么1.1 openclaw 和 Claude Code 的真实关系想搞明白这个报错得先看清楚 openclaw 和 Claude Code 在一条链路上各自扮演什么角色。openclaw 是调度层、编排层它自己不去 Anthropic 完成 OAuth 鉴权也不替你维护 Claude Code 的登录态。它的工作是接收微信、Web、Telegram 这些渠道侧的请求把请求翻译成可以被本机执行的指令然后拉起一个claude进程去干实事。也就是说Claude Code 的登录状态是“本机 claude 程序”自己的状态它存在你的用户目录下和 openclaw 有没有启动、配置了多少个 skill 都没关系。openclaw 只是在需要的时候去“借用”这个状态。一旦它借不到就只能在上游告诉你这家伙没登录。一个比较好懂的类比openclaw 就像代驾。它要开的是你这台车Claude Code得先确认能拿到油卡和行驶证。哪天它翻遍了你车里的手套箱、扶手箱都没找到证件它就会告诉你“这车没法开”。但事实上证件可能就在你裤兜里——问题不是你没证件而是它没找到地方。1.2 它查的其实是三样东西openclaw 判断 Claude Code 是否可用的逻辑抽象出来通常就三步检查claude这个可执行文件在不在 PATH 里检查登录凭证文件是否存在、是否能被当前进程读到真正发起一次最小调用看返回结果是 200 还是 401这三步里任何一步出了问题openclaw 都不会区分“进程环境不对”和“账号没登录”之间的区别——它统一给你报“claude code 未登录”。所以你会发现一个很反直觉的现象明明你本机的 claude 已经登录过了openclaw 却说没登录又或者你把 API Key 配好了它仍然说没登录。问题都不在你的 Anthropic 账号上而在 openclaw 进程的运行时环境上。1.3 不同检查阶段对应不同“假未登录”我把实际遇到过的情况整理成了下面这张表你可以先对号入座现象大概率卡在哪一步典型原因openclaw 日志里直接说找不到 claude 命令PATH 查找失败claude 装在~/.local/bin或 npm 全局目录但 openclaw 的 PATH 里没有这个目录命令能执行但立刻报未登录凭证文件读取失败HOME 环境变量变了进程去错误目录找.claude凭证凭证文件存在但请求仍然 401凭证内容失效token 过期、被撤销或者文件权限不够导致内容读到一半报错信息含糊只说“未登录”三项里至少一项失败通常是 HOME 不对或 claude 命令根本不在 PATH这三种情况的修复方式完全不一样。所以排障的第一步永远是先搞清楚 openclaw 到底卡在哪一步而不是急着重新登录。重新登录解决不了“目录不对”的问题就像你把钥匙揣进车库的柜子里却对着大门喊“开门”一样没有意义。2. Claude Code 的登录凭证到底存在哪一条路径引发的连锁故障2.1 登录凭证的落盘方式Claude Code 有几种登录方式对应的凭证存放方式也不同OAuth 方式执行claude login后浏览器里完成 Anthropic 账号的授权凭证会写到用户目录下~/.claude/目录里的某个隐藏文件中。常见的文件名是.credentials.json不同版本可能稍有差异但基本都落在这个目录下。这类文件一般权限是 600只有属主本人能读。API Key 方式执行claude login --api-key会把 key 写入配置目录也可以直接设置环境变量ANTHROPIC_API_KEY运行时不读取文件只认环境变量。企业代理或自建网关方式往往依赖ANTHROPIC_BASE_URL加上一个 API Key只要 key 能被读到就不存在“未登录”的概念。绝大多数人用的是第一种 OAuth 方式麻烦也就恰恰出在第一种方式上它是文件型凭证依赖一个不变的 HOME 路径。2.2 HOME 变量决定了一切CLI 工具查找配置目录的默认逻辑在 Linux 和 macOS 上都是读取$HOME环境变量然后拼出~/.claude/。理论上很简单但一旦经过 systemd、Docker、sudo、cron 这些“中间层”HOME 就不是你想象的那个值了。典型情况是你以普通用户alice登录系统claude login落盘在/home/alice/.claude/.credentials.jsonopenclaw 如果作为 systemd 服务运行配置里没有写User或者写了Userroot那它的 HOME 就是/root它会去/root/.claude/里找凭证结果自然是“未登录”还有一种隐蔽情况你用的是 macOS launchd 启动的服务HOME 可能是/var/root或者不设置效果和上面一样。2.3 sudo 是最常见的隐藏凶手很多时候你觉得自己已经登录过了但仔细回忆一下当时是不是用sudo claude login跑的命令一旦加了 sudo凭证就写到了 root 的 home 目录下。你当前用户的目录里干干净净什么都没有。后面你在自己终端里跑claude时它会用你当前用户的身份再去走一遍 OAuth 或者报未登录——你以为“登录成功”了其实是“root 成功”了。我之前处理过一个项目对方信誓旦旦说“我在服务器上登录过 Claude Code但 openclaw 就是报错”。我上去一查/root/.claude/.credentials.json存在/home/deploy/.claude/目录都没有。问题一目了然他先 sudo 登录了一次后面所有服务都以 deploy 用户运行。把凭证文件复制到 deploy 的目录调整属主再重启 openclaw立刻就好了。2.4 CLAUDE_CONFIG_DIR一个可以主动掌控的变量Claude Code 支持用环境变量CLAUDE_CONFIG_DIR来覆盖默认的配置目录位置。这个设计本意是给多环境隔离用的但在 openclaw 这种场景下它会成为你的救命稻草。你可以在 openclaw 的启动脚本或服务配置里强制指定export CLAUDE_CONFIG_DIR/home/alice/.claude这样一来不管 openclaw 进程的 HOME 被改成了什么它找凭证时都会回到你指定的绝对路径。这是最“指哪打哪”的做法比折腾 HOME 变量要精准得多。我建议你把登录好的凭证目录固定在一个明确的路径上比如/home/alice/.claude然后在所有相关服务的环境变量里都写上它。这能省掉后面一大堆权限和路径的破事。3. 一条条试出来用对照实验锁定“凭证不可见”的真凶3.1 第一组对照裸机 claude 是否正常任何排障都不要直接去翻 openclaw 的配置而是先建立一个“对照组”。首先确认在 openclaw 之外的干净终端里Claude Code 本身是否可用claude --version claude -p say okclaude -p是它的非交互模式会直接执行一句 prompt 并输出结果。如果这一步报“not logged in”或者要求登录说明问题根本不在 openclaw而是这台机器上的登录态已经失效了。你的修复动作应该是先在主机上解决登录问题比如重新执行claude login。如果这一步完全正常说明登录态本身是好的继续往下走。3.2 第二组对照模拟 openclaw 的进程环境这一步是关键中的关键。你要做的事情是找到 openclaw 进程到底是以什么用户、什么 HOME、什么 PATH 在运行的然后手动模拟这个环境去跑一次 claude。先找到 openclaw 的主进程pgrep -af openclaw然后看它的用户身份和环境变量ps -o user,pid,cmd -p 上一步拿到的PID cat /proc/PID/environ | tr \0 \n | grep -E HOME|USER|CLAUDE|ANTHROPIC|PATH对比一下输出和你在终端里的echo $HOME、echo $PATH大概率立刻就能发现问题。特别是 HOME只要不一致凭证路径就跟着错了。为了进一步验证你可以手动冒充 openclaw 的身份去执行一次sudo -u openclaw的运行用户 env HOMEopenclaw的HOME claude -p say ok如果这一步稳定复现“未登录”那就可以结案了openclaw 进程的环境和你登录凭证所在的环境不是一个用户或一个 HOME。接下来要做的就是把它们对齐。3.3 第三组检查凭证文件是否存在、属主是谁如果第二组实验没有复现问题那就再看看凭证文件的落盘情况ls -la ~/.claude/ stat -c %U %G %a %n ~/.claude/.credentials.json重点看三件事文件存不存在、属主是不是当前服务用户、权限位是不是 600。如果 openclaw 以 deploy 用户运行而凭证文件的属主是 root、权限又是 600那 deploy 用户即使知道文件路径也读不了内容等同于没登录。还有一种偏门情况你自己登录时没问题但如果 openclaw 跑在容器里容器内用户的 UID 和宿主用户的 UID 不一致同样读不了 600 权限的文件。这就是下一节要展开的容器场景。3.4 日志兜底看 openclaw 到底报的是哪类错误前面几步如果还定位不了就直接去看 openclaw 的日志。openclaw 的日志一般也在~/.openclaw/logs/或者你通过 systemd 的journalctl -u openclaw查看。搜这几个关键词claude、credential、auth、401、not logged in、permission denied。日志里通常能看出它到底是在执行之前做的检查失败还是真正发起请求后收到的 401。前者是环境问题后者才是凭证内容问题。我遇到过一次很刁钻的例子日志里一直报 401但凭证文件、目录、权限全都正常。浪费了半天时间最后发现是系统时钟偏了将近十分钟OAuth 的 token 校验直接把请求拒了。所以如果你把环境对齐之后还报 401顺手看一眼date的输出也没坏处。3.5 排查结论速查表你观察到的现象说明下一步动作裸机 claude 直接报未登录主机登录态失效重新 claude login再回来测裸机正常模拟 openclaw 环境后报未登录进程用户或 HOME 不对对齐环境变量或复制凭证到目标用户目录凭证文件存在但无读权限属主或权限位不对chown 改属主或 chmod 600 重新授权环境全都正确仍然 401token 过期/撤销或时钟偏差删除凭证重新登录检查系统时间日志提到 command not foundPATH 里没有 claude在 openclaw 配置中指定 claude 的绝对路径4. 修复方案按部署方式对号入座本机、容器和配置层各改什么4.1 本机直装 / systemd把用户和 HOME 对齐如果你是直接把 openclaw 装在本机并通过 systemd 托管那问题多半出在 service 配置和你的用户环境不一致。打开 systemd 的服务配置systemctl cat openclaw检查[Service]段里的User和Environment。如果User是 root而你的凭证存在/home/alice/.claude下那么需要把服务改成你的用户并显式补上 HOME[Service] Useralice EnvironmentHOME/home/alice EnvironmentPATH/home/alice/.local/bin:/usr/local/bin:/usr/bin:/bin EnvironmentCLAUDE_CONFIG_DIR/home/alice/.claude改完之后sudo systemctl daemon-reload sudo systemctl restart openclaw改完顺手再验证 service 环境下的凭证可见性sudo systemctl show openclaw -p Environment sudo -u alice env HOME/home/alice claude -p say ok这里有个小经验不要只改User就完事很多服务即使把用户改对了HOME 变量还是继承不到。只要是在 systemd 里运行建议每次都把HOME和CLAUDE_CONFIG_DIR显式写出来。写得越清楚后面越省事。4.2 Docker / 容器挂载凭证目录 环境变量注入容器场景比本机复杂一点因为容器内有一个独立的文件系统和独立的用户体系。如果你用 docker run 启动 openclaw需要在启动参数里把宿主机的凭证目录挂载进去同时把 HOME 指到挂载路径上docker run -d \ --name openclaw \ -v /home/alice/.claude:/home/alice/.claude \ -v /home/alice/.openclaw:/home/alice/.openclaw \ -e HOME/home/alice \ -e USERalice \ -e CLAUDE_CONFIG_DIR/home/alice/.claude \ your-openclaw-image如果用 docker compose对应的配置是services: openclaw: image: your-openclaw-image volumes: - /home/alice/.claude:/home/alice/.claude - /home/alice/.openclaw:/home/alice/.openclaw environment: - HOME/home/alice - USERalice - CLAUDE_CONFIG_DIR/home/alice/.claude这里有两个坑最容易踩第一个坑是容器镜像里根本没装claude。凭证路径挂进容器了但镜像里找不到claude命令openclaw 一样会报错。你需要在镜像里先装好 Claude Code或者通过挂载把宿主机的claude可执行文件也带进去。最简单的方式是在 Dockerfile 里增加安装步骤而不是依赖宿主机路径。第二个坑是容器内的用户 UID 和宿主机的 UID 不一致。宿主机上凭证文件权限是 600、属主 UID 是 1000容器里如果以 UID 0root运行倒还好root 有读取优先权但如果容器配置了user: 1001这样的指定用户UID 对不上文件就读不了。建议容器内用户 UID 与宿主机保持一致或者在启动时带上user: ${UID}:${GID}4.3 改用 API Key绕开文件凭证的终极手段如果你觉得 OAuth 文件凭证的路径、权限、挂载这套东西太烦还有一个更直接的办法不依赖文件凭证改用 API Key。在 Anthropic 的控制台里生成一个 API Key然后把环境变量注入 openclaw 的运行环境export ANTHROPIC_API_KEY你的key或者在 systemd / compose 的环境变量里直接写进去。API Key 模式下Claude Code 运行时不去解析~/.claude/.credentials.json而是优先从环境变量里读 key。只要进程环境里存在这个变量登录检查就不会失败。这种做法的好处是稳定几乎不受 HOME、用户、容器挂载这些因素影响坏处是要自己管理 key 的生命周期还要注意 API Key 的计费和订阅是两套逻辑别混着用。如果你只是想让 openclaw 调本地 Claude Code 跑自动化任务不考虑个人订阅账号的需求API Key 这条路可以认真考虑。但如果你的目标是把自己订阅的 Claude 额度用起来那还是回到 OAuth 凭证方案把环境对齐做好。4.4 三种方案怎么选方案适用场景优点缺点对齐 HOME / 用户 / CLAUDE_CONFIG_DIR本机直装、systemd 托管保留 OAuth 登录态符合个人订阅场景需要动服务配置稍微有点繁琐Docker 挂载凭证目录容器化部署不破坏镜像保留登录态挂载权限、UID 匹配有坑API Key 注入追求稳定、自动化任务为主环境问题最少最不容易被路径坑到需要自己管 key计费方式不同大多数情况下我会建议你先尝试方案一。它不改变你的使用习惯只要把环境对齐问题就能解决而且最接近“在使用者视角下唯一正确的状态”。容器环境建议方案二但要做好踩坑准备。如果你已经被这个问题折腾了两三个小时不妨直接切方案三稳定压倒一切。5. 一次修好之后怎么防止它再次“假装未登录”5.1 三十秒健康检查脚本问题修复之后强烈建议写一个最小化的健康检查脚本放在 openclaw 的启动目录或者你常用的~/bin/下。脚本核心就三行#!/usr/bin/env bash echo HOME$HOME echo CLAUDE_CONFIG_DIR${CLAUDE_CONFIG_DIR:-未设置} claude -p reply with ok /dev/null 21 echo claude OK || echo claude FAIL以后每次升级 openclaw、重启机器、或者改了环境变量之后手动跑一遍这个脚本几秒钟就能确认凭证是否可见。还可以把它接到 openclaw 启动前的自检里一旦检查失败就直接报错提醒而不是让 openclaw 启动后干等。5.2 凡是升级先备份再重登Claude Code 和 openclaw 都算更新频率比较高的工具。每次升级前先把凭证目录备份一份cp -r ~/.claude ~/.claude.bak.$(date %Y%m%d)升级之后如果发现登录态丢了先别急着重新登录把.credentials.json这个文件单独看一下还在不在。大多数情况下升级不会删凭证但如果真遇到了备份能让你快速恢复不用重新走一遍 OAuth 流程。另一个经验是升级 openclaw 后如果你改了它的启动方式比如从裸机进程换成了 systemd或者从本机换成了容器一定要重新过一遍前面说的健康检查。这不叫多此一举这叫你为自己的自动化流程负责。5.3 启动脚本里把环境变量写死不管用哪种方式跑 openclaw建议把关键环境变量固化下来而不是依赖“系统碰巧给了正确值”。我个人的习惯是HOME显式指定CLAUDE_CONFIG_DIR显式指定PATH里包含 claude 可执行文件所在目录配置文件里记录 claude 的绝对路径这样做的代价是多写几行配置收益是以后再也不会因为不知道哪个服务改了 HOME 而排查半天。环境变量这种问题越显式越安全。另外尽量避免用sudo去执行任何和 Claude Code 登录相关的命令。如果确实需要切换用户操作先用sudo -u 用户 -i切到那个用户的完整登录环境再执行登录确保凭证写对地方。5.4 别把“换模型”和“登录态”混为一谈最后补充一个容易混淆的点。很多人会用 openclaw 更换 gateway 模型比如接入 DeepSeek、硅基流动、本地 Ollama 等然后回过头来发现 Claude Code 报了未登录就以为两者有关联跑去检查 openclaw 的模型配置折腾半天找不到问题。其实这是两条独立的链路openclaw 的 gateway 决定的是“调度层用哪个模型来理解你的指令”而 Claude Code 的登录态决定的是“本机 claude 进程能不能使用 Anthropic 的服务”。你换了 gateway 模型并不会让 Claude Code 的登录凭证失效同理Claude Code 的未登录报错也不是靠换 gateway 模型能解决的。遇到问题先分清是“调度层”还是“执行层”出了状况能省下大量无用功。说到底openclaw 调用本机 Claude Code 报未登录这件事几乎从来不是玄学。它就是凭证、环境、权限三者之间的一次错位凭证在但 openclaw 的进程环境看不到或者环境对但凭证本身已经过期了。本文这套排查链路从裸机对照、模拟进程环境、检查凭证落盘到日志兜底可以解决掉九成以上的同类问题。剩下的那一成大多是不同版本之间配置路径或文件名的细节差异沿着一层层的分离对比思路去拆也能快速定位。我自己现在养成的习惯是在 openclaw 的启动文件里把 HOME 和 CLAUDE_CONFIG_DIR 写得明明白白升级完工具立刻跑一遍健康检查几乎再没被这个“假未登录”骚扰过。希望这篇记录也能帮你把这条路理顺少走几步弯路。