Repository navigation
A delegated child waiting on a permission approval never wakes its parent #26294
Description
What happened
Two delegate_task children (Claude, claude-opus-5-5, spawned with bypassPermissions) each sat for about 2 hours on a command permission request. The parent got no completion and no notice. task_status showed pendingApproval with a request id, but t3_pending_request read on that id returned "not found", and t3_thread_organize settle on the child refused with "is waiting on an approval or question". The only way out was task_cancel.
Why (read on upstream/main d0b81ce; the reactor and settle checks are unchanged on 0c80751)
DelegatedTaskQuestionReactor.tswakes the parent only foruser_inputrequests (it filters onrequest.kind !== "user_input"). A permission request gets no wake message.t3_pending_requestcovers questions only by design: "approvals are not listed … this cannot approve a permission request" (toolkits/thread/tools.ts:126).readQuestionlooks only forkind === "user_input", so an approval id comes back as "The pending user-input request was not found."pendingApprovalon the delegate result does surface it ("Oldest pending approval … Ends a wait. Grants no approval rights.",contracts/orchestratorMcp.ts:208), but only to a parent that happens to poll or wait.- Settle refuses while any non-
user_inputrequest is pending (Orchestrator.ts~3060).
So a child blocked on an approval is invisible unless the parent polls, and once found it can't be answered from MCP or settled.
It also leaks. After task_cancel, the approval on the cancelled child is still pending, so settle keeps refusing ("waiting on an approval or question"). No agent tool can answer a permission request, so the child thread keeps its provider session and MCP processes until a human clicks through it in the UI. (Interrupting a run does cancel its pending requests with "The run was interrupted." via settleInterruptedRun; the cancel path evidently didn't reach that here. We didn't trace why.)
Ask (any one helps; we'd take them in this order)
- Wake the parent on a pending approval, the same way the question reactor does for questions: a notification saying which child, which request kind, and that a human must approve it in the UI.
- Make
t3_pending_requestreadon an approval id say what it is ("this is a permission approval; agents can't answer it") instead of "not found". - Put the approval text in that wake. It already exists:
t3_thread_readactivity on a third stalled child showed theapproval_requesttext ("Dangerous rm operation on working directory or its ancestor: /scratch/..."). A parent that gets told which child and why can tell the user what to approve. - Make
task_cancelcancel the child's pending approvals, like a run interrupt does, so a cancelled child can settle.
Agents answering approvals is reasonably out of scope; we're asking for visibility, not approval rights.
Why a bypassPermissions child asked at all: Claude Code's own safety check refuses to rm a directory that contains the shell's current working directory, and it asks even under bypassPermissions. The child had cd'd into the directory it then removed. That check is correct; the T3 gap is only that nobody hears about it.
Activity
Dropje97 commentedon Oct 28, 2026
Additional version and timing evidence on
0.1.3-nightly.20261027.3754, Linux x64 (Debian 13). A Claude Fable 5.1 parent delegated to Claude Opus 5.5. Provider initialization records confirm Claude Code2.1.311,bypassPermissions, and T3 Full access. Codex CLI0.165.0is installed at inspection; these approval cases are Claude-specific observations.The server has local SQLite read-performance patches. The delegated-request reactor, MCP service, question handlers and tool definitions match upstream
d2c440312e5f39d59827ed466838a623516454d6byte for byte. No clean-release reproduction was run.All times below are 2026-10-28 UTC, from persisted requests and tool results:
03:09:25.054Z: a child opened acommandapproval withfullAccessOverride: provider_check. Claude's reason was “Dangerous rm operation not ruled out — the shell may read this command differently than it was parsed.”05:28:51.121Z: the parent'st3_pending_request(action: list, threadId: child)returned{"requestIds":[]}while that approval was pending, 2 h 19 min later. The parent had to inspect the child to discover the stall.05:29:46.043Z: the child's run was interrupted. The approval was still recorded as pending at inspection, so interruption did not clear it in this case either (related cleanup issue: [Bug]: Command approvals stay pending after a delegated task is cancelled #21935).09:44:36.025Zand09:55:27.131Z, resolving at09:44:55.177Zand09:56:05.131Z. Both wereprovider_checkrequests for statically unresolvable wildcard removal targets. Paths omitted.We now avoid the flagged cleanup commands. The missing behavior is a parent notice identifying the child, request kind and reason, and directing the user to the approval UI. Agent approval rights need not change. #22925 already tracks that notification path and its fix #20928 remains open and unmerged; these observations do not test that PR.
EtanHey commentedon Oct 28, 2026
Rechecked on 2026-10-28 through T3 Code's built-in triage playbook with Codex / GPT-6.1 Sol.
Installed/running nightly on both Macs:
0.1.4-nightly.20261028.3814. Latest published nightly checked in source:0.1.4-nightly.20261028.3824(eb751fa0730d6a51d56547cb7fcaf4822a7e0e3b); it is not yet running on these Macs.DelegatedTaskQuestionReactor.tsis unchanged between those tags. Its event path still returns unlessevent.payload.kind === "user_input", and its catch-up path likewise skips non-user_inputrequests. The primary missing approval-notification behavior therefore remains. Related #22925 is still open; proposed fix #20928 is still open and unmerged at this check.Keeping this open. No fresh dangerous-command approval was induced, and this recheck does not independently establish whether every cancellation/approval-cleanup subcase remains. Multi-machine orchestration does not change the reactor's request-kind filter.
fix(claude): full access denies Claude safety checks instead of waiting