
Codex CLI 全局安装失败常见两种脸孔npm install -g openai/codex报 EACCES或 sudo 装完zsh: command not found: codex。本地修好后模型通道还可能配不通TaoToken就管后半段打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_content 拿 Key把 Codex CLI 的 Base URL 指到 https://taotoken.net/api。前面那截 npm 权限和 PATH 还得在本地自己修两者别混成一件事。很多人的排查顺序是反的命令都找不到就先怀疑模型服务结果在配置里来回改越改越乱。更省事的切法是先把本地这条链路走通——which codex有输出、codex --version有版本号再看它请求发去了哪里。下面按报错现场、npm 全局目录、nvm 切换、config.toml 接入、验证、对照排障走一遍每一步都能单独停下来检查。1. npm install -g openai/codex 报 EACCES 的现场1.1 三条报错其实指向三件不同的事终端里最常看到的第一条是Error: EACCES: permission denied, access /usr/local/lib/node_modules这是 npm 想往系统目录写文件但当前用户没权限。第二条是sudo npm install -g openai/codex明明显示安装成功敲codex却是zsh: command not found: codex这是 PATH 里没有 npm 全局 bin 目录或者 sudo 把包装到了 root 的路径下。第三条是 nvm 用户切了 Node 版本之后命令凭空消失因为每个 Node 版本的全局包是各存各的。分清这三类之后再动手能省掉一半试错。EACCES 改的是 npm prefixcommand not found 改的是 shell 的 PATHnvm 丢包则是版本隔离的正常行为不是装坏了。原文统计里权限不足约占 40%、PATH 缺失约占 25%、nvm 切换丢失约占 15%这三项加起来就是绝大多数场景。# 先确认现状三条命令分别看安装位置、bin 目录、当前 Node which codex npm config get prefix node -v npm -v1.2 为什么全局安装总要碰 /usr/localnpm 默认把全局包装进/usr/local/lib/node_modules可执行文件软链到/usr/local/bin这两个目录在 macOS 和多数 Linux 发行版上都归 root。用 Homebrew 装的 Node 会换成/opt/homebrew那套目录权限宽松所以有人换 Node 来源之后问题自动消失。本质不是 Codex 特殊而是任何-g安装都会走同一条路。知道这一点方案选择就清楚了要么把 npm 的全局目录从系统目录搬到你自己的家目录要么让 Node 本身跑在用户目录里nvm、fnm、volta 都属于这类要么用 npx 干脆不装。sudo 之所以不推荐是因为它把文件所有者变成 root下次更新、卸载可能还要 sudo权限状态会越来越乱。# 能不用 sudo 就不用先看看当前 prefix 落在哪 npm config get prefix # 输出 /usr/local 说明是系统目录后面会改成用户目录2. 把 npm 全局目录搬到用户目录2.1 mkdir ~/.npm-global 与 npm config set prefix这是通用性最好的做法改动只影响当前用户不碰系统目录之后所有npm install -g都不需要 sudo。四步建目录、改 prefix、写 PATH、重装。注意顺序先改 prefix 再装否则旧包装在系统目录里which codex还是会指向老地方。# 1. 建一个属于当前用户的全局目录 mkdir -p ~/.npm-global # 2. 让 npm 把全局包装到这里 npm config set prefix $HOME/.npm-global # 3. 让 shell 能找到这个目录下的可执行文件 echo export PATH$HOME/.npm-global/bin:$PATH ~/.zshrc source ~/.zshrc # 4. 重新安装 Codex CLI npm install -g openai/codex # 5. 验证 which codex codex --version2.2 把 bin 目录写进 zshrc 并验证 which codex第 3 步最容易漏。改了 prefix 却不改 PATH装是装上了命令照样找不到。写进~/.zshrc之后必须source一次或者新开一个终端窗口否则当前会话的 PATH 还是旧的。判断有没有生效用echo $PATH看有没有~/.npm-global/bin这一段用npm bin -g部分 npm 版本已废弃该命令可直接用npm config get prefix拼/bin核对目录是否一致。如果之前用 sudo 装过先把旧的那份卸掉避免两个 codex 打架sudo npm uninstall -g openai/codex npm cache clean --force npm install -g openai/codexlatest which -a codex # 列出所有同名命令确认只剩一个which -a这个参数值得记住。它能一次性列出 PATH 中所有匹配项比which只显示第一个有用得多——当系统目录里还留着一个旧版本时你看到的版本号可能来自那份残留。3. nvm 环境下重装 Codex 与切换版本3.1 nvm 的全局包为什么切版本就消失nvm 给每个 Node 版本单独准备了一套 lib 和 bin全局包装在~/.nvm/versions/node/v22.x.x/lib/node_modules/下。nvm use 20之后PATH 指向的是 v20 的 bin 目录v22 里装的 codex 自然就找不到了。这不是 bug是设计使然所以 nvm 用户的正确习惯是每个要用的 Node 版本各装一次。nvm install 22 nvm use 22 nvm alias default 22 npm install -g openai/codex codex --versionnvm 装的 Node全局目录天然在用户家目录里所以完全不需要 sudo这点比系统 Node 省心。nvm alias default 22是让新开的终端默认用 22否则每次重启都要手动nvm use。3.2 每个 Node 版本重装一次的正确姿势如果你确实需要在多个 Node 版本间来回切可以写个小函数放进~/.zshrc省得每次记不住装没装codex_ensure() { if ! command -v codex /dev/null 21; then echo 当前 Node $(node -v) 没装 codex正在安装... npm install -g openai/codexlatest fi codex --version }另外两个备选路径也值得知道。不想装全局的用npx openai/codexlatest直接跑代价是每次要检查下载。想更彻底的用 fnm 或 volta 替代 nvmvolta 会把全局工具绑定到项目或用户级别切 Node 时工具跟着走不会丢。哪个顺手用哪个核心诉求只有一个让codex这个命令在任何目录下都能被找到。# 临时用一次的写法不装全局 npx openai/codexlatest --version # 想长期偷懒可以加个别名 echo alias codexnpx openai/codexlatest ~/.zshrc source ~/.zshrc4. codex 能跑了但模型通道配不通4.1 先拿 Key去 TaoToken 控制台创建到这一步codex --version应该能正常输出版本号了。接下来如果发请求报鉴权失败、连不通、找不到模型问题就不在 npm 侧而在 Codex CLI 的模型通道配置。Codex 默认指向的地址需要换成你自己的通道Key 也要换成你自己的。打开 TaoToken 注册并登录在控制台创建一把 API Key复制出来先放好。注意区分两个地址给人点的页面是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_content 填进 Codex 配置文件的 Base URL 是https://taotoken.net/api末尾不要加/v1。这两者不能互换配置里加了/v1通常会得到 404。模型 ID 不要凭记忆写。打开模型广场看当前可用的列表把你要用的那个 ID 原样复制避免因为名字差一个后缀而报模型不存在。4.2 config.toml 里写 model_provider 与 base_urlCodex CLI 的配置文件在~/.codex/config.toml没有就新建。要点是自定义一个 provider把base_url指向 TaoToken 的接口地址用env_key声明从哪个环境变量读 Key。# ~/.codex/config.toml model YOUR_MODEL_ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chatKey 不建议直接写在配置文件里用环境变量更干净echo export TAOTOKEN_API_KEYYOUR_API_KEY ~/.zshrc source ~/.zshrc这里的YOUR_MODEL_ID换成你在模型广场看到的实际 IDYOUR_API_KEY换成刚才创建的那把。注意别把 Claude Code 那套ANTHROPIC_*变量套到 Codex 上两者读的配置项完全不同混用只会得到莫名其妙的报错。4.3 环境变量方式与 profile 切换如果你需要频繁在多个通道之间切换用 profile 比来回改主配置方便# ~/.codex/config.toml 追加 [profiles.taotoken] model YOUR_MODEL_ID model_provider taotoken之后用codex --profile taotoken启动默认配置不动。适合同时保留几个不同用途的通道的场景也方便你把测试配置和生产配置分开。改完配置后记得新开一个终端或在当前会话里重新 source 一次让环境变量生效。5. 验证请求真的发出去了5.1 从 codex --version 到一次最小对话验证分两层。第一层是命令层确认二进制没问题which codex codex --version codex --help第二层是请求层随便提一个简单问题看它能不能拿到回复。如果这一步卡住或报错把完整报错信息留下来对照下一节的状态码来定位。请求层通了才说明 Key、Base URL、模型 ID 三样都对上了。5.2 回控制台核对这次调用请求发出后去看一眼调用记录确认这次请求确实记在了你的账号上。这一步能帮你区分请求根本没发出去和发出去了但被拒。如果记录里什么都没有问题多半在本地配置没被读取如果有记录但报错那就要看返回的具体信息。回到 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_content 的控制台在用量或日志页面核对刚才那次调用的模型和时间。确认无误之后Codex CLI 的整条链路就算通了。6. 排障对照401、404、多了 /v1、模型 ID 不存在6.1 状态码与配置的对应关系现象常见原因处理方向401 / 鉴权失败Key 没读到或写错检查环境变量名与env_key是否一致echo $TAOTOKEN_API_KEY是否有值404Base URL 多了/v1或路径拼错改回https://taotoken.net/api末尾不加斜杠和版本段模型不存在模型 ID 写错或已下架以模型广场当前列表为准原样复制超时 / 连不上网络环境或代理设置干扰检查本地代理变量确认请求确实发向配置的地址改了配置没生效终端没重新加载新开窗口或重新 source确认读的是同一份 config.toml404 这一条最常见也最好修。很多人习惯性在 Base URL 后面补/v1但这里的接口地址本身已经包含了正确的路径结构多写一段反而会被当成不存在的路由。6.2 缓存与旧配置的坑还有两个不明显的情况值得单独说。一是 npm 缓存导致装的是旧版 Codexcodex --version显示的版本比预期低这时npm cache clean --force再重装latest通常能解决。二是配置文件有多个来源比如同时存在旧的 profile 和新的 provider 定义实际生效的未必是你刚改的那段删掉冗余段再试更省事。# 确认到底加载了哪个版本的 codex which -a codex npm list -g openai/codex # 确认配置文件内容 cat ~/.codex/config.toml7. 把 Codex 的模型通道固定下来排障做完建议把有效的那套配置固定住别再靠临时命令。三个习惯把TAOTOKEN_API_KEY写进 shell 的启动文件而不是每次手敲把~/.codex/config.toml里的 provider 段保留成模板换模型时只改model一行Node 版本用 nvm 的default固定避免某天新开终端突然发现 codex 又不见了。以后再遇到 Codex 报错先按顺序问自己四个问题which codex有输出吗codex --version正常吗echo $TAOTOKEN_API_KEY有值吗Base URL 是不是https://taotoken.net/api且没带/v1。这四个问题覆盖了绝大多数情况能省掉反复卸载重装的时间。配好之后想确认套餐是否够用可以去 Coding Plan 看看想再建一把备用 Key在 控制台 API Keys 里操作想先用同一把 Key 快速试一句话直接开 模型对话 发条消息比在终端里猜哪一步没生效快得多。