Skip to content

ACP: a sub-agent that needs approval waits forever; the request never reaches the client #1465

Open

Description

@juliusmarminge

With fx acp in ask mode, a sub-agent that needs tool approval never finishes. fx moves the child to awaiting_approval, but never sends the ACP client a session/request_permission, or anything else. The parent's subagent tool call stays in_progress, and session/prompt never returns. The only way out is cancelling the turn.

Repro

fx 0.0.14. The code path is unchanged on main at e71a663.

  1. Set "permission_mode": "ask" in ~/.fx/settings.json.
  2. Create a workspace containing a package.json and a tsconfig.json.
  3. Run the attached probe: node acp-subagent-probe.mjs <path-to-fx> <workspace> out.ndjson. It:
    • sends initialize and session/new;
    • prompts "Spawn 2 subagents, one to read package.json and one to read tsconfig.json";
    • approves any session/request_permission with allow_once;
    • logs every frame.
  4. One child finishes in about 6 s: its tool_call_update is completed. The other's tool call stays in_progress. No permission request or other frame follows, and the prompt never returns; the probe gives up after 240 s.
  5. The session's subagent/children.json shows that child with "phase":"awaiting_approval" and "permission_mode":"ask".

It happened every time: three of three runs, from this probe, from T3 Code, and from T3 Code's replay recorder. In auto mode, the same prompt completes.

Where it seems to come from

  • runSubagentChild runs the child with the parent's tool context.
  • When the child needs approval, TurnContext.registerApproval moves it to awaiting_approval and registers the request in the sub-agent approval registry.
  • Only the terminal app drains that registry, via pendingApprovalRequest / resolveApproval in input_approval_runtime.zig and app_worker_runtime.zig. Nothing under src/acp calls either function, so over ACP the request is never shown to the user and never resolved.

Expected

The child's approval reaches the client as a session/request_permission on the parent session, ideally saying which sub-agent asks, and the client's answer resolves it. If fx can't route it, the child should fail rather than wait forever.

Attachments

Found while adding fx to T3 Code (pingdotgg/t3code#18277). T3 Code shows fx sub-agents in their own threads, and for now tells users to switch to Auto when delegating.

Activity

  1. suirindo commented on Oct 27, 2026

    @suirindo

    For the approval-routing fix, a deterministic regression could put two children in awaiting_approval at once, reject one request, and approve the other. Assert that each answer resolves only its originating child and that the rejected child's tool produces no side effect.

    A second case can cancel the parent while a permission request is outstanding, then deliver a late allow_once response. The late response should not restart the cancelled child, and session/prompt should settle with the defined cancellation result. This would cover request correlation and lifecycle cleanup alongside the reported missing request_permission frame. I haven't rerun the attached probe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions