Repository navigation
Description
Client or integration
Codex CLI
Area
CLI
Summary
~/.codex/opencodex.config.toml is rebuilt from a fixed template on every Codex injection, so any key an operator adds to that profile is silently dropped. The generated header tells the user to run codex --profile opencodex, and nothing in the file or in the command output says that its contents are not preserved.
In our case we add two Codex stream settings to the profile (stream_idle_timeout_ms and stream_max_retries). They are present after we write them and gone minutes after the next start, with no message. Expected: keys OpenCodex does not manage survive a reinjection, or the write names the keys it dropped.
Cause in the published 2.94.0 source:
src/codex/inject/config-toml.ts:641—buildProfileFileForTarget()returns a fixed template built from the routing target, catalog path, websockets flag, fast mode and display name. It never reads the file it is about to replace.src/codex/inject/plan.ts:326— every injection plan calls it.src/codex/inject.ts:493— the plan output is published over~/.codex/opencodex.config.tomlwithatomicWriteFile.
Proposed fix: read the existing profile before writing and carry over keys OpenCodex does not manage, the same expectation #7425 states for ~/.codex/config.toml. If carrying keys over is not wanted, at least say which keys were dropped, and give the stream settings a supported surface so they do not have to live in a generated file. Our current workaround is a start hook that re-applies the two keys after every start, which is how we noticed the overwrite.
Reproduction
- On a machine where OpenCodex injects the Codex configuration (2.94.0, after
ocx startorocx sync), open~/.codex/opencodex.config.toml. - Add one root key that OpenCodex does not generate, for example
stream_idle_timeout_ms = 240000next tomodel_provider = "opencodex". - Run the injection again (restart the proxy, or run
ocx sync). - Observe that the added key is gone and the file equals the generated template again. No warning is printed.
Version
2.94.0
Operating system
macOS (Apple silicon)
Provider and model
Not provider-specific. This is the Codex config write; no model request is needed to see it. Our install routes Codex through the local proxy (model_provider = "opencodex"), so the provider-table form of the profile is the one we observe.
Logs or error output
No error and no warning. The only evidence is the before/after diff of the file; the write is an atomic replace with the newly built content.
Screenshots and supporting files
None.
Redacted configuration
# before the next injection: the operator key is present
model_provider = "opencodex"
model_catalog_json = "<catalog path>"
stream_idle_timeout_ms = 240000
stream_max_retries = 3
# after the next injection: the template is back and the operator keys are gone
model_provider = "opencodex"
model_catalog_json = "<catalog path>"Related: #7425 (same expectation for ~/.codex/config.toml), #817 (a root key removed on inject).
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
github-actions commentedon Nov 1, 2026
Automated translation bookkeeping — detected language: English.
lidge-jun commentedon Nov 3, 2026
Fixed on
devby #8074 (14692ab): OpenCodex now keeps Codex profile keys it does not manage when it regenerates the profile. It ships in the next release; please reopen if it still reproduces after updating.