Codex Desktop native Planner rejects a verified read-only parent with `BLOCKED_PARENT_NOT_READ_ONLY`

Open 💬 3 comments Opened Aug 25, 2026 by fxhuanghfx
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using?

Codex Desktop 26.819.11345.

What platform is your computer?

macOS.

What issue are you seeing?

A fresh Codex Desktop thread created while Configuration → Sandbox settings = Read only is correctly observed by the outer task as an effective read-only session, but a native Planner/subagent dispatch from that same thread fails immediately with:

BLOCKED_PARENT_NOT_READ_ONLY

In the reproduced case, the outer routing/permission checks all passed before dispatch:

current thread: fresh Planner thread
effective session permission: read-only
routing validation: PASS

The native Planner then returned only the blocker string above instead of the expected structured Planner result. A downstream validator consequently failed with a schema error because the native result was a string rather than a mapping.

This looks like a permission-propagation contradiction between the Desktop thread's effective runtime sandbox and the permission state seen by the spawned native Planner.

Steps to reproduce

  1. Open Codex Desktop on macOS.
  2. In Configuration, set Sandbox settings to Read only.
  3. While that setting remains Read only, create a brand-new task/thread intended for a read-only Planner role.
  4. Verify from the live task that the effective session is read-only.
  5. Invoke the native Planner/subagent dispatch from that thread.
  6. Observe that the native child immediately returns:
BLOCKED_PARENT_NOT_READ_ONLY
  1. The parent remains read-only and unchanged; no files are modified and no plan is produced.

This was reproduced after creating a fresh replacement read-only thread; simply naming/registering the thread as read-only was not relied upon. The live effective session itself was read-only at dispatch time.

Expected behavior

If the parent thread's effective sandbox is read-only, a native Planner/subagent that requires a read-only parent should accept that parent and dispatch normally.

At minimum, the child should observe the same effective parent permission state that the parent/runtime reports.

If native Planner requires a stricter or separately persisted permission field, Codex Desktop should expose that field clearly and provide a supported way to create/verify a compliant Planner thread.

Actual behavior

The outer thread reports and operates as read-only, but the native Planner rejects the parent as not read-only.

This blocks canonical Planner workflows even though the user has deliberately created a fresh thread under Read only settings.

Impact

  • Canonical multi-agent planning can deadlock at dispatch time.
  • Users may repeatedly create replacement read-only threads with no improvement.
  • Automation/orchestration must either stop or fall back to a non-native planning path.
  • The failure is especially confusing because the UI and outer runtime both show read-only while the child reports the opposite.

Related issues

  • #15305 — review-mode subagent ignores the parent thread's runtime sandbox override and falls back to config defaults.
  • #32705 — MultiAgentV2 child permission profiles can be overwritten/inherited inconsistently from the parent.
  • #25810 / #29503 — Desktop thread creation/UI permission state can diverge from persisted/effective sandbox state on other surfaces.

This may be another manifestation of the same permission-propagation class, but this report is specifically about a native Planner rejecting an already verified read-only parent as not read-only.

Suggested regression test

  1. Start a fresh Desktop parent thread with effective read-only sandbox.
  2. Assert the parent turn context is read-only.
  3. Spawn the native Planner/review-style child that requires a read-only parent.
  4. Assert the child sees the parent as read-only and dispatches successfully.
  5. Repeat after changing the Desktop sandbox selector before thread creation and after a full Desktop restart.

No private repository names, local paths, thread IDs, user data, secrets, or screenshots are included here.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 3 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #40278

Powered by Codex Action

fxhuanghfx · 3 days ago

Update after a full Codex Desktop restart:

The original BLOCKED_PARENT_NOT_READ_ONLY failure changed, which suggests the restart cleared at least part of the stale permission-propagation state.

Post-restart observations from the same fresh read-only Planner thread:

  • Live/effective session permission: read-only
  • Native Planner dispatch now starts successfully instead of immediately returning BLOCKED_PARENT_NOT_READ_ONLY
  • Native Planner returns PLAN_READY
  • However, the returned payload is plain-text plan content rather than the structured mapping/envelope expected by the canonical validator
  • Canonical validation therefore fails with:
SchemaError: native Agent result must be a mapping

No plan was materialized and no task/product state was modified after the validation failure.

This suggests two separable issues in the same workflow:

  1. Permission propagation / parent sandbox state — improved after a full Desktop restart.
  2. Native Planner result transport/serialization — the Planner can now run, but its result reaches the parent as plain text rather than the structured mapping expected by the validator.

The second failure is reproducible immediately after restart, with the parent still verified read-only.

A useful regression test would therefore cover the full chain:

  1. Start a fresh read-only parent thread.
  2. Spawn the native Planner.
  3. Assert the Planner sees the parent as read-only.
  4. Assert the Planner returns the expected structured result type/envelope, not only plain text such as PLAN_READY plus prose.
  5. Pass that exact native result unchanged through the canonical validator.

This follow-up does not include private repository names, task IDs, local paths, user data, secrets, or screenshots.

fxhuanghfx · 2 days ago

Cross-reference with #40605: together these issues form a single blocker chain for reliable 24/7 role-separated engineering loops.

In the reproduced workflow, the sequence was:

  1. A dedicated read-only Planner parent was correctly configured and externally observed as read-only.
  2. Native Planner initially rejected it with BLOCKED_PARENT_NOT_READ_ONLY (#40549).
  3. After a full Codex Desktop restart, that permission failure disappeared, but the Planner then returned PLAN_READY as plain text rather than the structured mapping/envelope expected by the validator; the downstream validator failed with SchemaError: native Agent result must be a mapping.
  4. Even after a usable planning result existed, the separate workspace-write implementation thread could not reliably retrieve the exact Planner output through the supported cross-thread reader. The user had to manually copy/paste the full result into the write-side thread (#40605).

This means fixing only one layer is not enough for unattended engineering. A complete least-privilege loop needs all of the following to work end-to-end:

  • parent/child permission propagation must be consistent;
  • native role output must preserve the expected machine-readable result contract;
  • the completed result must be durably retrievable by the authorized downstream thread, byte/text-exact with provenance/hash;
  • restart/resume must preserve the handoff.

The intended topology is deliberately permission-separated:

read-only Planner/Reviewer/Tester -> exact immutable result handoff -> workspace-write Implementer -> tests/review -> next loop

Without a first-class exact-result receipt/handoff, every permission boundary reintroduces a human copy/paste step and breaks true unattended / 24/7 autonomous operation.