[Desktop remote] Full Access conflict-merges with inherited root deny and bricks the task
Summary
In an existing Codex Desktop task backed by a saved remote SSH project, selecting Full Access was accepted correctly by the app-server, but the subsequent thread-settings resolution conflict-merged Full Access with an inherited custom filesystem restriction.
The UI and active label remained :danger-full-access, while the effective policy became a malformed managed profile containing both:
- filesystem root:
write - filesystem root:
denywithescalatable=false
The resulting turn had sandbox_mode=read-only / no writable roots. Bubblewrap then omitted Codex's own native binary path, so even pwd failed before the shell started with execvp ... No such file or directory.
Environment
- Originator: Codex Desktop
- Codex CLI/package/app-server native binary:
0.146.0 - Desktop UI build number: not present in the remote-side logs
- Execution surface: saved remote SSH project into an OrbStack VM
- Remote OS: Ubuntu 25.10
- Kernel: Linux
7.0.11-orbstack-00360-gc9bc4d96ac70 - Architecture:
aarch64 - Codex install: global npm package under
/usr/lib/node_modules/@openai/codex - Custom default permission profile: anonymized below as
remote-workspace; it contains a non-escalatable root deny
Minimal reproduction
- Start and use a remote Codex Desktop task with a custom default permission profile containing a non-escalatable root deny.
- Allow an automatic goal continuation/resume to start another turn in the existing task.
- Select Full Access in Codex Desktop and submit a prompt.
- Observe that the app-server handler receives built-in
Disabled/ active:danger-full-accesscorrectly. - Observe that
thread_settings_appliedretains the:danger-full-accesslabel but produces an effective managed profile containing both root write and root deny. - Ask the agent to run
pwd.
Actual result:
bwrap: execvp /usr/lib/node_modules/@openai/codex/node_modules/@openai/codex-linux-arm64/vendor/aarch64-unknown-linux-musl/bin/codex: No such file or directory
The binary exists and is executable in the remote host namespace. Changing the requested shell, login-shell mode, and working directory does not change the failure because it occurs before the command starts.
Event-log evidence
The evidence was collected read-only from the affected rollout JSONL and ~/.codex/logs_2.sqlite. User names, task IDs, private repository names, and secrets have been removed.
The affected rollout was initially healthy:
2026-08-08T05:29:18.583Z: workspace-write policy with a valid workspace root
The malformed binding first appeared at automatic goal continuation:
2026-08-08T05:46:52.389Z: effective filesystem becomes{root write, root deny(non-escalatable)}; sandbox is read-only and writable roots are empty2026-08-08T05:47:15.761Z: first Bubblewrapexecvpfailure
The Full Access application path reproduced three times:
07:48:23.559048Z:codex_core::session::handlers(core/src/session/handlers.rs:700) receives incoming Full Access asDisabled / :danger-full-access
07:48:23.565Z:thread_settings_appliedrecords the Full Access label but conflicting root write + root deny effective bytes07:48:23.602Z: the emitted turn context is restricted with no writable roots
- The same transition repeats at
07:49:07.422221Z → 07:49:07.431Z → 07:49:07.487Z - It repeats again at
07:49:40.648434Z → 07:49:40.656Z → 07:49:40.693Z
The same malformed permission binding was redistributed to multiple child turns in the affected task tree, so this was not a one-off Bubblewrap process failure.
This isolates the corruption boundary to after the session handler correctly receives Full Access and before thread_settings_applied emits the effective profile. The evidence strongly suggests that built-in Full Access root-write permissions and the custom/default profile's non-escalatable root-deny rule are being field-wise conflict-merged instead of Full Access atomically replacing the managed profile.
Expected behavior
Selecting Full Access should atomically produce:
permission_profile.type=disabledsandbox_mode=danger-full-access- unrestricted filesystem access
- no inherited deny entries from the previously active/default managed profile
The label shown by the UI and recorded as active must match the effective policy delivered to the turn. If profile resolution produces conflicting root rules, the turn should fail visibly before execution rather than silently displaying Full Access.
Codex's own resolved native binary/package path should also remain available inside any generated Bubblewrap namespace, even if a permission profile is malformed.
Impact
- An existing task can become completely unable to execute commands.
- Re-selecting Full Access does not repair it.
approval_policy=neverplus a non-escalatable deny leaves no in-task recovery path.- Child turns inherit the malformed binding.
- The UI reports Full Access while the effective runtime is read-only.
Workaround observed
Creating a fresh task through the same saved remote project produced a fresh disabled/Full Access session. In the same VM and workspace, pwd, Git operations, and non-interactive sudo then worked normally. No host-side filesystem access or repository repair was required.
Related issues
- #32338 — permission dropdown and effective runtime profile desynchronize or merge between prompts
- #31269 — configured permission profile stops being used after the first prompt
- #29049 — restricted filesystem profile hides Codex's own runtime binary
- #20906 — Bubblewrap cannot execute the native binary when its package path is excluded
This report connects those symptoms with a repeated app-server event boundary and a concrete root-write/root-deny conflict merge on a Linux remote execution target.
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action