App-server config write APIs cannot target project .codex/config.toml (user config only)
What version of Codex is running?
Observed on openai/codex current main in v0.101.0.
What issue are you seeing?
config/read can resolve and return project layers (.codex/config.toml) when cwd is provided, but config/value/write and config/batchWrite reject writing to project config paths and only allow writes to $CODEX_HOME/config.toml.
This makes project-scoped config effectively read-only through the app-server protocol.
Steps to reproduce
- Create a repo with a trusted project and a project config file:
<repo>/.codex/config.toml
- Call
config/readwithcwd=<repo>andincludeLayers=true.
- Observe a
Projectlayer inlayers, and/ororiginspointing toProject.
- Attempt to write a project-scoped key using:
config/value/writewithfilePath="<repo>/.codex/config.toml"(or equivalent absolute path),- or
config/batchWritewith that samefilePath.
- Observe error response:
config_write_error_code: "configLayerReadonly"- message:
Only writes to the user config are allowed
- If
filePathis omitted, the write succeeds but updates$CODEX_HOME/config.toml(user/global scope), not project scope.
Expected behavior
One of these (in order of preference):
- Support project-layer writes in config RPC:
- explicit targeting, e.g.
targetLayer: "project"+cwd, or - allow
filePathto point at trusted.codex/config.tomlwith guardrails.
- If project writes are intentionally unsupported, make that explicit in protocol/docs and narrow
filePathsemantics to avoid implying arbitrary writable config target files.
Actual behavior
Write APIs are hard-restricted to user config path, even when the protocol can read project layers.
Why this matters
Protocol clients can read effective/project config but cannot persist project-scoped changes.
They must mutate global user config instead, which leaks project-specific settings across repositories.
Additional context (source references)
ConfigReadParams.cwdexplicitly describes project-layer resolution.ConfigValueWriteParams.file_path/ConfigBatchWriteParams.file_pathaccept a path and say it defaults to user config when omitted.core/src/config/service.rsenforces:- allowed write target =
$CODEX_HOME/config.toml - otherwise returns
ConfigLayerReadonlywith messageOnly writes to the user config are allowed. - App-server README currently describes write RPCs as writing user config.
Happy to help test a fix if there is a preferred API shape.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗