Skip to content

[Bug]: ACP spawn fails with "requester denies apply_patch" when caller session uses claude-cli backend (loopback MCP dedup leaks into inherited deny) #89241

@shadow-enthusiast

Description

@shadow-enthusiast

Describe the bug

When the caller session runs on a claude-cli backend (any model with agentRuntime: claude-cli), spawning an ACP child via sessions_spawn({ runtime: "acp" }) is rejected:

runtime="acp" is unavailable because the requester denies apply_patch.
Use runtime="subagent".

No tool deny policy is configured — the deny originates from the loopback MCP bridge dedup list (NATIVE_TOOL_EXCLUDE) being treated as an inherited policy deny.

Root cause (source trace)

  1. mcp-http.runtime.ts defines NATIVE_TOOL_EXCLUDE = {read, write, edit, apply_patch, exec, process} — tools the CLI harness provides natively, excluded from the MCP loopback bridge to avoid duplicates.

  2. tool-resolution.ts (resolveGatewayScopedTools) receives these via params.excludeToolNames and merges them into explicitDenylist:

    excludedToolNames.length > 0 ? { deny: excludedToolNames } : void 0
  3. The same function then copies the full denylist into inheritedToolDenylist:

    const inheritedToolDenylist = [...explicitDenylist];
  4. acp-spawn.ts calls findAcpUnsupportedInheritedToolDeny(ctx.inheritedToolDenylist), which checks against ACP_UNSUPPORTED_INHERITED_TOOL_DENY — a list that includes apply_patch, edit, exec, process, read, write (all present in NATIVE_TOOL_EXCLUDE).

  5. Result: ACP spawn is hard-blocked because the dedup exclusion list is indistinguishable from a security policy deny.

Why this is a bug

NATIVE_TOOL_EXCLUDE is a deduplication optimization — the CLI harness already provides these tools natively, so the loopback bridge doesn't re-expose them. This is not a security restriction and should not be inherited by child sessions.

PR #80979 (2026-05-13, "Inherit tool restrictions for delegated sessions") introduced inheritedToolDenylist propagation. The intent was correct (inherit real policy denies), but the implementation doesn't distinguish dedup exclusions from policy denies.

Steps to reproduce

  1. Configure a model with agentRuntime: claude-cli (e.g., anthropic/claude-opus-4-8 via CLI backend)
  2. Set the session model to that CLI-backed model
  3. Attempt sessions_spawn({ runtime: "acp", agentId: "claude", task: "echo test" })
  4. Observe: spawn rejected with requester denies apply_patch

Switching to any API-backed model (e.g., litellm/claude-opus-4-6) on the same session and retrying — succeeds immediately. No config changes needed.

Expected behavior

ACP spawn should succeed regardless of whether the caller session uses a CLI backend or an API backend, as long as no explicit tool deny policy is configured.

Actual behavior

ACP spawn is blocked when the caller uses any claude-cli backend model.

Suggested fix

In tool-resolution.ts, excludeToolNames (loopback dedup) should not be included in inheritedToolDenylist. They should only filter the current session's tool set:

// Current (broken):
const inheritedToolDenylist = [...explicitDenylist];

// Proposed: separate dedup exclusions from policy denies
const inheritedToolDenylist = [...policyOnlyDenylist]; // without excludeToolNames

Environment

  • OpenClaw version: 2026.5.28
  • OS: Debian 13 (arm64)
  • CLI backend: Claude Code 2.1.157
  • ACP backend: acpx

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions