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

Closed as duplicate

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).

Activity

  1. juliusmarminge commented on Oct 12, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.#18852 is the 401 form of this bug. After Claude → Codex → Claude → Codex inside Codex's 30-minute idle window, Codex keeps a revoked MCP credential and every T3 tool returns "Authentication required". PR #17096 lists this as a known limit. A complete fix needs per-(thread, provider instance) credentials, or releasing the previous provider's session on switch.

  2. Alb11747 commented on Oct 13, 2026

    @Alb11747
    Contributor

    Prepared the focused sequential switch-back repair in #18884. It refreshes the reused native MCP client as well as the server credential, preserves peer conversations, and covers retained starts and interrupted issuance. Focused tests pass; the linked fork CI is running. Live provider-switch verification remains untested.

  3. added 12 commits that reference this issue on Oct 14, 2026
    f3cb349
    dc8f1a5
    e1863c4
    95904e4
    166b700
    39c36c5
    8faeb74
    38928df
    43a8991
    7c16bb3
    fcd3623
    1185a77
  4. 60 remaining items

  5. added 4 commits that reference this issue on Nov 11, 2026
    d8559e3
    40530ef
    0fc181f
    f96f65e
  6. Alb11747 commented on Nov 12, 2026

    @Alb11747
    Contributor

    A fresh fix from current main is in #35331. It replaces #19413, which was closed as stale with a request to open a new PR from main. The regression test there fails on main at 2482b03 (after an A → B → A switch, the first provider's token no longer resolves) and passes with the fix.

    I already have more open PRs than the open PR limit allows, so the limit check may close #35331 on arrival. If you'd like it reviewed, a maintainer can reopen it, add triage:keep-open so I can reopen it, or add me to the PR limit exemptions.

    🤖 Generated with Claude Code

  7. juliusmarminge commented on Nov 12, 2026

    @juliusmarminge
    Member

    This is the same problem as #23198, so I'm closing it in favour of that one. If it is different, say how and it will be reopened.

  8. bompus commented on Nov 12, 2026

    @bompus
    Contributor

    I tested whether #23198 fixes this, because I believe it does not.

    #23198 releases the previous provider session when a thread sends to another provider instance (#20343). The problem here is the MCP token store, which McpProviderSessions keys by thread only. After a thread goes A → B → A, the store holds B's entry for that thread, and the first provider's token no longer resolves.

    I ran the regression test "preserves MCP access through A → B → A and isolates cleanup" from #35331 (by @Alb11747) in a throwaway worktree on main at fc2b5de, which contains #23198's merge c0ec87a (git merge-base --is-ancestor exits 0):

    The test and the fix are theirs; I only ran them.

  9. added 2 commits that reference this issue on Nov 13, 2026
    fac8f14
    7f66cc6
  10. Alb11747 commented on Nov 13, 2026

    @Alb11747
    Contributor

    This still happens on current main (eb14ddb, which includes #23198). Repro and details are in #36453.

    Posted by Claude Opus 5.5 on behalf of Alb11747.

  11. added 4 commits that reference this issue on Nov 14, 2026
    e7a7bee
    7fa5d60
    a2a91f2
    e48558f
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