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

Open

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. 47 remaining items

  5. jamesdchen commented on Nov 1, 2026

    @jamesdchen

    Seeing this with Antigravity on T3 Code server 0.1.6 (Windows x64), and every message came from the mobile app. Here it's the 401 form of the bug, and it does more than break tool calls: Antigravity can't start the t3-code MCP server, so the whole turn fails and the thread can't be used.

    What happened, in one thread:

    1. Run 1, Antigravity (Gemini): a long turn finished normally and called t3-code tools along the way (t3_project_list, t3_environment_read, html_preview, html_render).
    2. Run 2, Claude Code (claudeAgent, Opus): I switched the thread to Claude. That account was at its weekly limit, so the turn failed right away with Claude API rate limit reached. This switch would have rotated the thread's MCP credential.
    3. Run 3, back to Antigravity (Claude Opus model): the turn ended in about 6 seconds. The only output was:
      The MCP server 't3-code' failed to initialize: calling "initialize": T3 Code MCP endpoint responded with HTTP 401. Fix the MCP server, or remove it from your configuration and start a new session, to continue.
      
    4. Run 4, still Antigravity, model changed to Gemini: same 401 error after about 3 seconds. Changing the model inside the same provider doesn't open a new session, so the revoked token is still in use.

    Both failed runs were recorded as completed, with the error text posted as the assistant's message (the same run-status problem as #20097 and #20260).

    So it's the same sequence as above: provider A → provider B (B issues a new token and revokes A's) → back to A, which reuses its old session and keeps the revoked token. With Antigravity, though, a failed MCP initialize blocks every turn, not just T3 tool calls. On mobile there's no way to get out of it except opening a new thread.

    Also: I only switched back to Antigravity in step 3 because mobile gives me no way to move Opus to another Claude login when one hits its limit (#28872).

  6. added 14 commits that reference this issue on Nov 5, 2026
    67dfbce
    7aa0237
    1173c34
    35c7322
    450fe97
    5995ac1
    0c94908
    a94d3b6
    cab3065
    b0ac71d
    3770652
    8d5cdef
    d8559e3
    40530ef
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