Codex App version
26.803.5235.0
Platform
- Microsoft Windows 11 Pro
- Version
10.0.22631, build 22631
- x64 native Windows desktop app
Summary
The permission selector in the Codex Desktop composer was permanently disabled/greyed out, including while the thread was idle. The selected label could change between "Ask for approval" and "Full access", but the control itself could not be opened or changed.
The problem was caused by a stale persisted state value with a legacy boolean shape:
"composer-permission-mode-visibility": false
The current app bundle expects an object for this persisted atom:
{
"guardian-approvals": true,
"full-access": true
}
Because the old value is the non-nullish boolean false, the current fallback logic does not replace it with the object default. Both configurable permission modes consequently remain hidden/disabled.
Relevant implementation observed in the installed app bundle
The installed app.asar contains the equivalent of:
const defaultVisibility = {
"guardian-approvals": true,
"full-access": true,
};
const persistedVisibility = persistedAtom(
"composer-permission-mode-visibility",
defaultVisibility,
);
function resolveVisibility(value) {
return value ?? defaultVisibility;
}
A persisted false passes through value ?? defaultVisibility unchanged. Downstream code expects an object and derives the visible permission modes from it.
Steps to reproduce
- Have the persisted global state contain:
"composer-permission-mode-visibility": false
- Launch Codex Desktop on Windows.
- Open a local task and wait until no turn is running.
- Try to open the permission selector in the composer.
- Observe that the permission label is greyed out and cannot be changed.
Changing approval_policy, sandbox_mode, or default_permissions in config.toml did not make the selector interactive.
Important persistence behavior
Editing the state file while Codex was running did not fix the problem. On shutdown, the app wrote the already-loaded legacy false value back to disk.
The successful recovery required:
- Fully exit all processes belonging to the Codex app package.
- Replace the legacy boolean after process exit with:
"composer-permission-mode-visibility": {
"guardian-approvals": true,
"full-access": true
}
- Relaunch Codex.
After that, the permission selector became interactive again and Full Access could be selected successfully.
Expected behavior
Codex should migrate or normalize legacy persisted values. If the stored value is not an object with the expected keys, it should fall back to the current default visibility object.
For example, the resolver should validate the type rather than only using nullish coalescing.
Actual behavior
The legacy boolean is accepted as a valid persisted value, leaving the permission selector permanently disabled. Normal restarts and permission-related config.toml changes do not repair it.
Suggested fix
- Add a persisted-state migration from boolean values to the current object shape.
- Validate that the loaded value is an object before using it.
- Fall back to the default visibility object for
false, true, malformed objects, or unknown values.
- Add a regression test covering a profile upgraded with the legacy boolean value.
- Consider exposing a supported in-app reset for only the permission-selector state.
Related issues
This report is specifically about the stale persisted boolean schema and the verified after-process-exit repair.
Privacy
Usernames, task IDs, prompts, repository names, and local project paths are intentionally omitted.
Codex App version
26.803.5235.0Platform
10.0.22631, build22631Summary
The permission selector in the Codex Desktop composer was permanently disabled/greyed out, including while the thread was idle. The selected label could change between "Ask for approval" and "Full access", but the control itself could not be opened or changed.
The problem was caused by a stale persisted state value with a legacy boolean shape:
The current app bundle expects an object for this persisted atom:
{ "guardian-approvals": true, "full-access": true }Because the old value is the non-nullish boolean
false, the current fallback logic does not replace it with the object default. Both configurable permission modes consequently remain hidden/disabled.Relevant implementation observed in the installed app bundle
The installed
app.asarcontains the equivalent of:A persisted
falsepasses throughvalue ?? defaultVisibilityunchanged. Downstream code expects an object and derives the visible permission modes from it.Steps to reproduce
Changing
approval_policy,sandbox_mode, ordefault_permissionsinconfig.tomldid not make the selector interactive.Important persistence behavior
Editing the state file while Codex was running did not fix the problem. On shutdown, the app wrote the already-loaded legacy
falsevalue back to disk.The successful recovery required:
After that, the permission selector became interactive again and Full Access could be selected successfully.
Expected behavior
Codex should migrate or normalize legacy persisted values. If the stored value is not an object with the expected keys, it should fall back to the current default visibility object.
For example, the resolver should validate the type rather than only using nullish coalescing.
Actual behavior
The legacy boolean is accepted as a valid persisted value, leaving the permission selector permanently disabled. Normal restarts and permission-related
config.tomlchanges do not repair it.Suggested fix
false,true, malformed objects, or unknown values.Related issues
This report is specifically about the stale persisted boolean schema and the verified after-process-exit repair.
Privacy
Usernames, task IDs, prompts, repository names, and local project paths are intentionally omitted.