PowerShell 里改了 config.toml,Codex CLI 仍用旧值:先分清该改哪一层
在 PowerShell 里保存 config.toml 后,当前 Codex CLI 会话还是旧值,先不要在几份同名文件之间来回试改。
这份文件保存的是后续会话的默认设置。用户级写个人习惯,项目级写这个仓库的约定。先分清自己该改哪一层,再判断是文件被写回去了,还是更高层盖住了刚保存的值。
本文按 Codex CLI 0.147.0 的配置行为说明,最后核验日期为 2026-08-12。
先按这条最短路径走,细节在后面各节:
- 分清该改用户配置还是项目配置。
- 打开刚改的同一份文件,确认新值还在。
- 确认这次启动读的就是这一份。
- 从高到低找盖住新值的那一层。
config.toml 到底是干什么的?
config.toml 是 Codex CLI 的持久配置文件。常用模型、审批与沙箱方式、MCP 服务器这些希望下次打开还在的设置,可以写在这里。
改它是为了固定"以后默认怎样",不是为了改"当前这个已经开着的窗口"。文件保存后,已经启动的会话不会被强制刷新。启动参数、启动时选择的 Profile,以及会话里的临时选择,也可能让当前窗口继续用另一套值。
最常见的用户配置路径是 ~/.codex/config.toml。~ 代表当前用户的主目录,在 PowerShell 中输入 $HOME 就能看到实际位置。它常被叫作"全局配置",但只对当前系统用户生效,并不会共享给电脑上的其他用户。
用户配置和项目配置分别用在什么时候?
两份文件可以同名,但使用场景不同。按希望影响的范围来选,不要先比较哪一份看起来更高级。
用户配置适合保存你这个人在这台电脑上的习惯,例如日常模型和自己习惯的审批基线。默认路径就是 ~/.codex/config.toml。换一个仓库再启动,这些个人习惯通常还在。
项目配置适合保存这个仓库自己的约定,路径是受信任仓库中的 <repo>/.codex/config.toml。它只影响从该项目范围启动的会话,适合写成"这个仓库必须更谨慎"。认证、供应商、通知、Profile 选择和遥测这类只属于本机的设置,不要放进项目配置。
只有仓库里某个子目录需要不同约定时,再在那个范围放更近的项目配置。同名设置同时存在时,项目值会盖住用户值;离当前工作目录更近的启用层会继续盖住外层项目配置。
例如,用户配置里的日常审批是:
toml
approval_policy = "on-request"
某个受信任项目需要更谨慎的审批,于是在项目配置中写入:
toml
approval_policy = "untrusted"
从这个项目启动新会话时,用的是项目约定 untrusted,不是个人习惯 on-request。离开这个项目并清掉其他覆盖后,会回到用户级的 on-request。
on-request 默认允许命令在沙箱内执行,越过沙箱边界时再请求批准;untrusted 则会对可信集合以外的命令请求批准。这里改的是命令审批策略,不是后文用来启用项目配置的项目信任状态。
示例只展示一个字段,要合并进现有文件,不能当作完整配置覆盖原内容。只是为了看覆盖关系而改时,先记下原值,看完再恢复。
所以可以按场景选择该改哪一层:
- 希望之后的个人会话都用这个默认值,修改用户配置。通常是
~/.codex/config.toml;如果后面的检查给出了不同的UserConfigPath,以检查结果为准。 - 设置只属于某个可信仓库,修改该仓库的
<repo>/.codex/config.toml。 - 只有仓库内某个子目录需要不同值,在那个范围使用更近的项目配置。
- 只想试验一次,不需要写入文件,使用 CLI 临时覆盖。
- 需要在几套独立配置之间切换,使用 Profile,并在启动时显式选择。
Profile 是启动时显式选择的一份独立配置。CLI flags 和 --config 只覆盖当前这次启动。
新值为什么会从文件里消失?
如果改的那一层是对的,但保存后会话仍是旧值,先重新打开刚改的同一份文件。
新值已经消失,先查是谁又写了这份文件;新值还在,再查这次启动实际读取的文件和覆盖层。
手工修改前先退出 Codex,避免交互界面和编辑器同时改同一路径。暂时不能退出时,不要让两者同时写同一份文件。模型选择、功能开关等明确保存动作可能写入磁盘,但不能把普通退出理解成一定会把文件改回去。
多数情况下,过一会儿再打开文件看内容就够了。
可选:只有已经怀疑同步工具、脚本、设置动作或供应商切换工具在后台写盘时,才继续查是谁在写这份文件。如果你使用 CC Switch 管理供应商,启用或同步时,它可能把自己管理的设置写给 Codex 实际读取的文件。手工修改后,应在 CC Switch 中同步保存同一项配置,或者避免再次执行会写入该文件的启用、同步动作。这时再在保存后立刻记下时间和哈希,隔一段时间或触发一次怀疑动作后再比一次。把 <CONFIG_TOML_ABSOLUTE_PATH> 换成刚才重新打开的同一份配置绝对路径。命令只显示最后写入时间、字节数和 SHA256,不打印配置内容。
powershell
$configPath = '<CONFIG_TOML_ABSOLUTE_PATH>'
$file = Get-Item -LiteralPath $configPath
$hash = Get-FileHash -LiteralPath $configPath -Algorithm SHA256
[pscustomobject]@{
Path = $file.FullName
LastWriteTimeUtc = $file.LastWriteTimeUtc
Length = $file.Length
SHA256 = $hash.Hash
}
结果变化说明文件又被写过。此时应暂停编辑器、同步工具、脚本或设置动作,找出由谁管理它,不要先进入配置优先级排查。
结果不变,说明这次检查没有发现文件被改回,可以继续查当前会话实际读取的配置。若命令提示文件不存在,先纠正路径,不要改另一份同名文件。
这次启动实际读的是哪份配置?
这一步要回答两个问题:当前终端把用户配置放在哪里,以及即将启动 Codex 的工作目录是不是目标项目。
没有额外设置时,用户配置就是 ~/.codex/config.toml。CODEX_HOME 是一个可选环境变量。当前终端设置了它之后,Codex 改用这个目录保存 config.toml 和其他本地文件。终端配置、启动脚本或父进程都可能传入这个值。Windows 原生终端、WSL 和其他 Shell 也可能得到不同结果。
把 <CONFIG_TOML_ABSOLUTE_PATH> 换成刚编辑的用户配置或项目配置绝对路径。下面的命令只检查路径是否存在,不读取文件内容。
在准备启动 Codex 的同一个 PowerShell 中运行:
powershell
$targetConfig = '<CONFIG_TOML_ABSOLUTE_PATH>'
$codexHome = [Environment]::GetEnvironmentVariable('CODEX_HOME', 'Process')
if ($null -eq $codexHome) {
$state = 'unset'
$userConfig = Join-Path (Join-Path $HOME '.codex') 'config.toml'
} elseif ([string]::IsNullOrWhiteSpace($codexHome)) {
$state = 'blank'
$userConfig = $null
} else {
$state = 'set'
$userConfig = Join-Path $codexHome 'config.toml'
}
[pscustomobject]@{
WorkingDirectory = (Get-Location).Path
CODEX_HOME_State = $state
UserConfigPath = $userConfig
UserConfigExists = $null -ne $userConfig -and (Test-Path -LiteralPath $userConfig -PathType Leaf)
TargetConfigPath = $targetConfig
TargetConfigExists = Test-Path -LiteralPath $targetConfig -PathType Leaf
}
如果实际从 Bash 或 Zsh 启动 Codex,对照同一组字段:工作目录、CODEX_HOME 状态、用户配置路径、目标文件是否存在。空值或纯空白同样要先改正,不要假设会回退到默认目录。完整命令见文末站内教程。
不要只看命令是否执行成功,要对照刚改的那份文件:
WorkingDirectory必须是准备启动 Codex 的目标项目目录;不对就先切换目录。CODEX_HOME_State为unset时,UserConfigPath是默认用户配置;为set时,它是自定义目录里的config.toml,这个目录必须已经存在。- 为
blank时,当前终端传入了空值或纯空白。Codex 不会自动回退到默认目录,先删除或改正这个变量。 - 如果改的是用户配置,
UserConfigPath应与TargetConfigPath是同一文件,TargetConfigExists应为True或true。两条路径不同,就不要继续修改原来的文件。
路径正确后,在目标项目的系统终端用严格模式启动 Codex CLI 0.147.0:
text
codex --strict-config
--strict-config 会把未知字段作为错误报告。看到 TOML 语法错误或未知字段,并显示对应文件路径、行号时,先按提示修正,直到能够进入 TUI。项目层禁用字段属于配置层限制,不是 TOML 语法错误。
进入目标项目的 TUI 后,用 /debug-config 列出当前会话发现的配置来源和启用状态。在消息输入区运行:
text
/debug-config
这是 TUI 斜杠命令,不是 PowerShell 命令。结果按低优先级到高优先级排列,并显示每一层的路径以及 enabled 或 disabled 状态;官方优先级列表采用相反的高到低顺序。
先核对用户文件路径是不是你刚改的那一份,再看从项目根到当前目录的项目层。越近且保持启用的层越优先。普通系统、用户和项目层只告诉你来源与状态,不会展开每个文件的完整键值,也不会直接指出每个最终值来自哪里,因此仍需打开可疑文件比较目标字段。分享输出前要删除本地路径和启动参数值。
看到项目层为 disabled 时,先读禁用原因。项目未受信任会让 Codex 跳过该 .codex 目录里的 config、hooks 和 rules。只有你已经确认项目及其内容可信,才把下面的小块合并到现有用户配置,并把占位符替换为 /debug-config 显示的项目绝对路径:
toml
[projects.'<TARGET_PROJECT_ABSOLUTE_PATH>']
trust_level = "trusted"
保存后重开会话,再运行 /debug-config。项目不可信时,应保持项目层禁用。
哪一层盖住了刚保存的新值?
官方配置优先级从高到低是:
- CLI flags 和
--config临时覆盖; - 从项目根到当前工作目录的项目配置,越靠近当前目录越优先;
- 启动时显式选择的 Profile;
- 用户配置;
- 系统配置;
- 内置默认值。
实际排查时不用比较整份文件,只追踪没有生效的字段。先看本次启动的 CLI 参数,再按从近到远检查项目配置,然后检查目标 Profile、用户配置和系统配置。找到第一个提供有效同名值的高优先级来源,就找到了覆盖位置。删除多余的临时覆盖,或回到真正负责这个值的文件修改。
如果项目层显示为启用,但某个字段仍没有作用,再确认该字段能否放在项目层。Provider、认证、通知、Profile 选择和遥测等机器本地设置要放回用户配置;例如项目 .codex/config.toml 里的 model_provider 会被忽略。这种忽略属于配置层限制,并不表示 TOML 写错了。
若输出出现组织 requirements.toml 或 policy 来源,本地配置排查应在这里停止。它是管理员施加的约束,记录来源和受影响设置后联系管理员,不要尝试用本地参数绕过。
怎样重开会话确认已经采用新值?
退出当前 TUI,回到已经确认的目标项目目录,并移除不再需要的旧 --profile、--config 或其他 CLI 临时覆盖。
预期值来自用户或项目配置时,重新启动:
text
codex
预期值来自 Profile 时,继续显式选择同一个 Profile:
text
codex --profile <TARGET_PROFILE>
进入 TUI 后,用 /status 检查新会话是否采用预期的审批策略。在消息输入区运行:
text
/status
/status 给出当前会话摘要,其中包含审批策略。在前面的例子中,从受信任项目启动且没有更高覆盖时,应看到项目级 untrusted 对应的状态;离开项目且没有其他覆盖时,应回到用户级 on-request。不一致就回到 /debug-config,重点检查仍启用的 CLI 或项目层。
/status 只确认当前会话采用的配置,不代表模型请求、第三方端点或需要权限的动作已经成功。
如果问题已经混入安装入口、认证或运行环境健康,可以在系统终端运行 codex doctor --summary。codex doctor 会读取本地状态并进行联网检查;--summary 只压缩显示,不会减少检查内容。若生成诊断报告,即使工具标记为已脱敏,分享前也要人工查看。
官方资料
- Configuration precedence:核对 CLI、项目、Profile、用户、系统和默认配置的官方优先级。
- Core locations 与 CODEX_HOME:确认用户配置和本地状态目录的规则。
- config.toml 配置参考:查询字段名称、类型与适用位置。
- Inspect your settings:了解怎样检查当前设置。
- Inspect config layers with
/debug-config:查看配置层、启用状态和禁用原因。 - Inspect the session with
/status:核对当前会话状态。 - Codex doctor:只在安装、认证或运行时健康也有问题时参考。
参考文档
分清该改用户级还是项目级,并找到覆盖来源之后,如果还要对照完整的跨 Shell 路径检查和持续更新说明,请看: