Skip to content

[Bug]: Remote delegate_task refused by linked environment's access ceiling reports it as "parent mode approval-required" #27317

Open

Description

@zielinskizack0

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

Server: MCP orchestration / Linked environments (remote delegate_task)

Steps to reproduce

  1. On machine A (Windows, v0.1.5), run a thread in Auto runtime mode.
  2. Link machine B (macOS) and choose the Approval required (supervised) access when approving the link. t3_environment_links on A then reports B as reachable with access: "approval-required".
  3. From the Auto thread on A, call delegate_task with runtimeMode: "auto" and target: { environmentId: <B>, projectId: <project on B>, ... }.

Expected behavior

The call is refused, which is correct: the link's access caps what A's agents can do on B. But the error should say that the link's access is the limit, for example:

Linked environment "" was linked with approval-required access, so a task there cannot run in auto. Omit runtimeMode to run it at approval-required, or link it again with broader access.

Ideally A checks this before forwarding, since A already knows the link's access.

Actual behavior

{"code":"runtime_mode_escalation_denied","message":"Child runtime mode auto is broader than parent mode approval-required."}

No child is created. The parent thread is in Auto, so "parent mode approval-required" is wrong from where the agent stands. Agents and users then go looking for a parent-mode or inheritance bug, or ask the user to switch a thread to Auto that is already Auto. Calling orchestrator_capabilities with B's environmentId adds to the confusion: it returns parentThreadId: null, inheritedProviderInstanceId: null, inheritedModel: null, runtimeMode: "approval-required", which looks like the caller's context was dropped. It is actually B's view of the link client, which has no thread.

Cause (from source, unchanged on main at 8970a32)

  • RemoteDelegation.delegate (apps/server/src/peer/RemoteDelegation.ts) checks resolveRuntimeMode(parent.thread.runtimeMode, input.runtimeMode) against A's parent (auto, so it passes), then forwards t3_thread_launch with runtimeMode: "auto".
  • On B, the caller is the link's OAuth client with no thread. So limits = clientModeCeiling(scope.client), which is the link's approved access (approval-required), narrowed by T3-Mode-Limit (McpInvocationContext.ts).
  • startsThreads then calls resolveRuntimeMode(caller.limits.runtimeMode, "auto"). The message in apps/server/src/mcp/delegatedTaskModes.ts always says "parent mode", even when the limit is a client or link ceiling.
  • PeerMcpClient.call re-raises B's failure code and message as-is, so nothing says the refusal came from the link's access.

Suggested fix

  1. In RemoteDelegation.delegate (and other forwarded launches), also check the requested mode against the link's access before forwarding, and fail with a message that names the link and its access.
  2. Make resolveRuntimeMode/resolveInteractionMode take a label for the limit's source (parent thread, client approval, link access), so the message isn't always "parent mode". This overlaps with the wording point in A lower-mode thread can't report back to the thread that launched it, and the refused send is invisible #26293.
  3. Optionally, let orchestrator_capabilities with an environmentId say that its runtimeMode is the link's ceiling, not an inherited parent mode.

Impact

Misleading error (not a security bypass): remote delegation works as a security boundary, but the refusal points at the wrong cause and leads to misdiagnosis.

Version or commit

Desktop + server 0.1.5 (current Latest). Code paths unchanged on main 8970a32.

Environment

Parent on Windows 11 (desktop app 0.1.5) in Auto, linked to a macOS machine with approval-required link access.

Workaround

  • Omit runtimeMode (or pass "inherit"). Going by the source (not tested), the task then runs on B at the link's ceiling (approval-required), and B asks for approvals.
  • Or have the user link B again with Auto access if they want Auto there. The parent being Auto doesn't help, because the link's access is the limit.

Activity

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