Skip to content

[Windows] Permission selector permanently disabled by stale boolean composer-permission-mode-visibility state #37423

Description

@psremilio

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

  1. Have the persisted global state contain:
    "composer-permission-mode-visibility": false
  2. Launch Codex Desktop on Windows.
  3. Open a local task and wait until no turn is running.
  4. Try to open the permission selector in the composer.
  5. 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:

  1. Fully exit all processes belonging to the Codex app package.
  2. Replace the legacy boolean after process exit with:
    "composer-permission-mode-visibility": {
      "guardian-approvals": true,
      "full-access": true
    }
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingsandboxIssues related to permissions or sandboxingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions