Skip to content

MCP token keeps the old provider after a thread switches back to a reused provider session; delegate_task fails with parent_not_active #16565

Description

@snnbotchway

What happened

Version: 0.0.46-nightly.20261005.2702 (Linux, systemd user service).

  1. Thread runs on Claude (claude_proxy). Its Claude provider session stays alive.

  2. The user switches the thread to Codex (codex_proxy, shared session). Codex attaches to the thread. prepareMcpSession(thread, codex_proxy) revokes the thread's credential and issues a Codex-scoped one into the per-thread slot.

  3. The user switches back to Claude. The old Claude provider session is still in sessions and still attached to the thread, so ensureThreadAttached does not call prepareMcpSession. The Claude process starts (--resume) with the token from the slot. That token is still scoped to codex_proxy.

  4. Every orchestration call that checks the live caller fails:

    • delegate_task: parent_not_active: Delegated tasks require an active run owned by this MCP provider session.
    • t3_queue_cancel: parent_not_active: The calling provider no longer owns an active thread run.

    The active run is correct (providerInstanceId: claude_proxy, rootNodeId set). The mismatch is scope.thread.providerInstanceId (codex_proxy).

Evidence: orchestration_v2_projection_provider_session_bindings lists both provider-instance:claude_proxy:thread:<id>:… and provider-instance:codex_proxy:shared for the thread. The trace shows no McpSessionRegistry.issue when the thread went back to Claude.

Expected

When a run starts on a provider, the thread's MCP credential is scoped to that provider. If the slot holds a credential for another provider, it is rotated, even when the provider session is reused.

Workaround

Restart the T3 service. The next run opens a fresh Claude session, which issues a correct token.

Possible fix

On each run start (or provider process spawn), call prepareMcpSession(threadId, run.providerInstanceId), not only when the thread is newly attached. Or keep one slot per thread and provider, not one per thread.

Related: #15173 (also about session reuse and delegated runs).

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