Skip to content

Resumed session fails every request with 400 "Tool reference '...' not found in available tools" after an MCP server's tools change between launches #5359

Open

Description

@doomslayer2k

Describe the bug

After a resume, every request in a session failed with:

Execution failed: 400 Tool reference 'kusto-<tool>' not found in available tools

(Tool name redacted. It was one of the two tools that an earlier tool search in the same session had returned.)

This included compaction. The session stayed unusable until we changed the MCP configuration. It failed on every request: we resumed it twice, about 21 minutes apart, and both resumes failed the same way.

What happened: early in the session, deferred-tool search returned tool_reference blocks for two tools of an MCP server named kusto. Those blocks stayed in the conversation history. Later, the session shut down while idle. When it was resumed, the server name kusto resolved to a different implementation that exposes different tool names. The engine still sends the historical tool_reference blocks. They now name tools that are not in the request's tool list, so the API rejects every request, including compaction, which sends the same history.

Extensions/plugins: not tested with plugins disabled. MCP configuration is the trigger: restoring the original server, with no other change, fixed the session.

Affected version

copilot-sdk-runtime-1.0.102-0.unstable (engine bundled with the GitHub Copilot desktop app 1.1.35, Windows)

Not yet retested on 1.0.105 or 1.0.106-x.

Steps to reproduce the behavior

These steps are reduced from the failure we observed. We have not run them in isolation.

  1. Configure an MCP server named foo that exposes a tool alpha, with deferred tools or tool search active.
  2. In a session, have the model find alpha through tool search, so a tool_reference for foo-alpha enters the history.
  3. Exit the session. Change the configuration so that the server named foo now exposes only beta. In our case, a workspace .mcp.json defining a server with the same name took precedence over the user-level definition. We expect any change that removes alpha to have the same effect.
  4. Resume the session and send any prompt.
    • Every prompt returns 400 Tool reference 'foo-alpha' not found in available tools.
    • /compact fails with the same error.

Expected behavior

A tool that no longer exists should not permanently break a resumed session. Any of these would fix it:

  • On resume, and before compaction, re-validate historical tool_reference blocks against the current tool list and drop the ones that no longer resolve.
  • Turn stale references into plain text, for example "tool foo-alpha was available earlier in this session but is no longer configured".
  • At minimum, show one clear error that names the missing server and tool and says how to recover, instead of failing every turn.

Additional context

Impact: the session is unusable. No prompt succeeds and compaction fails, so the session cannot recover by itself. Nothing in the UI points at MCP configuration as the cause. The only recovery is a configuration change.

Workaround (verified): make the server name resolve to the original implementation again. We redefined the original server under the same name in the workspace .mcp.json. The session then resumed and completed turns normally. To prevent a recurrence, give servers that could shadow each other distinct names.

How this differs from #4663: #4663 reports the same error string on the compaction path while the referenced tool still exists. It reportedly stopped reproducing on 1.0.82, and its suggested workaround is to resume the session. Here, the tool no longer exists after resume. Resuming is the trigger, not the fix, and every request fails, not only compaction. The backoff and error-surfacing that #4663 asks for would make this failure visible, but would not fix it. Also related: #4519 (closed), another 400 from replaying deferred-tool history.

Suggested labels: area:sessions, area:mcp, area:tools. We can't apply labels as an outside contributor.

Environment (collected by script; an unrelated crash section was trimmed):

App version         1.1.35
OS                  Windows 10 Enterprise 26H2 (build 26300.9711)
Architecture        AMD64
WebView2 runtime    156.0.4314.58
Copilot CLI         copilot-sdk-runtime-1.0.102-0.unstable.r41779900948.gf482387

Desktop app on Windows, git-worktree project session. No terminal emulator or shell is involved.

In-depth investigation

Timeline (2026-11-05 UTC)

  • Early in the session, a tool_search_tool_regex call returned tool_reference blocks for two tools of the kusto server.
  • Later, the session shut down while idle.
  • Resume 1 (02:51:55Z): the first request failed with 400 Tool reference 'kusto-<tool>' not found in available tools.
  • Resume 2 (03:12:54Z): failed identically.
  • We then redefined the original server under the name kusto in the workspace .mcp.json. After that, the session resumed and completed turns normally.

Why the server changed between launches. Two MCP configs define a server named kusto:

  • a user-level MCP config;
  • the repository's workspace .mcp.json, which takes precedence when present.

The session was created as a new git-worktree session. On first launch, the MCP configuration was read about 7.5 s before the worktree's .mcp.json was written, while the checkout was still running. So the first launch got the user-level server. The resume found the workspace file and got the other implementation.

That ordering is specific to our setup, but the engine-side problem is general. A resumed session replays tool_reference blocks without checking them against the tools it now has. So we expect any change to a server's tool set between launches (an upgrade, a renamed tool, or a same-named server in another config) to reach the same state.

Activity

  1. added
    area:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registry
    area:sessionsSession management, resume, history, session picker, and session state
    and removed on Nov 5, 2026
  2. doomslayer2k commented on Nov 11, 2026

    @doomslayer2k
    Author

    Hit this again with a different trigger, and this one needs no unusual setup: a routine app update that ships a new version of a bundled plugin.

    App 1.2.0 (engine 1.0.106-8) installed the bundled computer-use plugin 0.1.97. Its MCP server now exposes only exec_js and exec_js_reset, replacing the earlier per-action tools (get_window_state, list_apps, click, …). A long-running session was still running the old plugin, which it had started before the update. Through tool search it found computer-use-get_window_state and computer-use-list_apps. When the session was next resumed, it loaded the new plugin, and every request failed:

    Execution failed: 400 Tool reference 'computer-use-get_window_state' not found in available tools
    

    So any session that tool-searched the old Computer Use tools, and still replays that result (it came after the last compaction), should hit this when it is first resumed on 1.2.0. This applies to server-side tool search (tool_search_tool_regex), whose results carry tool_reference blocks. An older session that never compacted, and that holds only client-side tool_search_tool text results for the same tools, resumed fine on 1.2.0. The workaround in the original report (restore the old server) is not available here, because the update removed the old plugin version.

    Frequency: every request after the resume, until the history was repaired. Not intermittent.

    Workaround that worked: with the session's process stopped, rewrite the two stale tool_reference names in the stored assistant message so they name tools that still exist (computer-use-exec_js, computer-use-exec_js_reset), then resume. The next prompt succeeded and the session continued normally.

    Data point for the fix: that same assistant message also contains a plain tool_use block that calls the removed computer-use-list_apps. I left it unchanged, and the API accepted it. That suggests only the tool_reference blocks inside the tool-search result are checked against the current tool list. If so, sanitizing those on resume (and before compaction) should be enough.

    App version         1.2.0
    OS                  Windows 10 Enterprise 26H2 (build 26300.9911)
    Architecture        AMD64
    Copilot CLI         1.0.106-8
    computer-use plugin 0.1.97 (bundled)
    
    In-depth investigation

    Timeline (2026-11-10 → 11 UTC)

    • 15:45Z: the session resumes on the previous app version. Its tool list includes the per-action computer-use-* tools.
    • 17:52Z: the app updates to 1.2.0, which installs computer-use 0.1.97. The running session keeps the old server it already started.
    • 21:58Z: the model runs server-side tool search (tool_search_tool_regex, pattern computer-use-(list_apps|get_window_state)). The stored assistant message holds the server_tool_use block and a tool_search_tool_result with tool_reference blocks for computer-use-get_window_state and computer-use-list_apps, followed by a tool_use for computer-use-list_apps.
    • 23:22Z: last activity on the old process. That process later exits.
    • 05:17Z: resume on 1.2.0. The new server exposes only exec_js / exec_js_reset. The first prompt (05:21Z) fails with the 400 above.

    Why compaction doesn't save you: the tool search happened after the session's last successful compaction, so the reference sat in the replayed tail. Earlier tool searches for the same tools (weeks before) had been compacted away and were harmless.

    Repair: a byte-exact rewrite of the one event line: only the two tool_name values inside tool_reference blocks changed, and the bytes before and after that line were hash-verified unchanged. The thinking-block signature in the same message was left intact and the API did not object.

    Suggested labels: area:sessions, area:mcp, area:tools.

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

    area:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registryarea:sessionsSession management, resume, history, session picker, and session state

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions