Desktop app rewrites removed feature flag js_repl into config.toml on every startup
Open 💬 2 comments Opened May 25, 2026 by liby
Summary
The Codex desktop app writes features.js_repl = false back into config.toml on every launch, even when the user has manually removed the line. js_repl is reported as a removed-stage feature flag by codex features list.
Environment
- codex-cli 0.133.0
- Codex desktop app 26.519.41501
- macOS (Darwin 25.4.0, arm64)
Steps to reproduce
- Quit the Codex desktop app completely.
- Edit
$CODEX_HOME/config.tomland remove thefeatures.js_repl = falseline. - Confirm with
grep js_repl $CODEX_HOME/config.tomlthat the line is gone. - Run
codex features listandcodex doctor. The line stays absent; the CLI does not write it back. - Launch the Codex desktop app.
- Re-check
config.toml.features.js_repl = falseis present again.
Observed behavior
After every desktop-app launch, features.js_repl = false is restored.
Code reference
In the desktop bundle at Codex.app/Contents/Resources/app.asar, file .vite/build/main-*.js:
var Qn = [`features.js_repl`, /* ... */];
async function $n({ appServerConnection, desktopFeatureAvailability, ... }) {
let d = await St({ ... });
await appServerConnection.sendAppServerRequest(`config/batchWrite`, {
edits: er(d), // Qn.map(t => ({ keyPath: t, mergeStrategy: `replace`, value: d?.[t] ?? null }))
expectedVersion: null,
filePath: null,
reloadUserConfig: true,
});
}
$n is awaited during app startup. The features.js_repl keyPath is written with mergeStrategy: "replace" unconditionally.
CLI feature stage
$ codex features list | grep js_repl
js_repl removed false
js_repl_tools_only removed false
Impact
A user who deletes features.js_repl = false finds it restored on the next desktop-app launch, with no UI control to suppress the rewrite. This is confusing because the CLI reports the flag as removed.
2 Comments
Update: Confirmed that the
[mcp_servers.node_repl]block is also restored on every desktop-app launch via the sameconfig/batchWritecall. The second entry in the hardcoded keyPath list (mcp_servers.${e.wn}) resolves tomcp_servers.node_repl.So the desktop app unconditionally rewrites two keys on startup:
features.js_repl(set tofalse)mcp_servers.node_repl(full MCP server config block)Both reappear after manual deletion following the same reproduction steps described above.
Confirmed on the Rust side:
js_replandjs_repl_tools_onlyare removed feature keys, and config loading intentionally ignores them when present under[features].config/batchWritecan still persist arbitrary config edits toconfig.toml, so the Desktop bundle snippet in this issue points to startup sync as the likely source offeatures.js_repl = falsebeing restored. A fix should probably filter removed feature keys before issuing or persisting those startup config writes. The same pattern may also explain the reportedmcp_servers.node_replrestoration, but I only see that path from the bundle snippet here rather than checked-in Desktop source.