[BUG] Claude in Chrome: phantom tabs accept and answer javascript_tool execution after Chrome has closed them
Summary
tabs_context_mcp reports a tab that Chrome itself lists under Recently Closed. Unlike
previously-reported stale-listing bugs, this phantom tab is not merely present in a cached list —
it accepts tool calls and returns plausible live-looking results. navigate, javascript_tool,find, and computer all succeed against a target the browser no longer exposes to the user.
The result is a silent dead end: every tool reports success, the agent believes it is driving a real
tab, and the user is repeatedly asked to interact with a tab that does not exist in their browser.
The failure is undetectable from the agent side without out-of-band evidence (OS window enumeration,
or a screenshot of Chrome's own tab search).
This appears related to but distinct from #34030 (stale/cached tab data), which describes stale
listings. Here the phantom target is also executable.
Environment
- Windows 11 Pro 10.0.26200
- Chrome, single instance, single profile (
--user-data-dir=C:\Users\micha\AppData\Local\Google\Chrome\User Data) - Claude Code CLI with
claude-in-chromeMCP tools - Single visible Chrome window confirmed via Win32
EnumWindows
Reproduction
- Start a Claude Code session with Claude in Chrome connected; obtain a tab via
tabs_context_mcp {createIfEmpty: true} (tab id 342544959 in this run).
- Drive that tab through a long automation task (repeatedly opening/closing a modal on a
JS-heavy SPA). The renderer eventually becomes unresponsive and the tab dies.
- Close all Chrome windows. Reopen Chrome.
- Call
tabs_context_mcpagain.
Expected: a fresh tab list reflecting current browser state; the dead tab absent, and any new tab
carrying a newly-issued id.
Actual: the same tab id 342544959 is returned, with the document.title this session had
previously assigned to it still intact — across a full browser restart. Real Chrome tab ids are not
stable across restarts, so this value cannot have come from the live browser.
Evidence that the tab does not exist
1. Chrome disagrees. Chrome's own tab search (Ctrl+Shift+A) lists exactly two open tabs
(chrome://newtab, claude.com). The MyPractice tab appears under Recently Closed, timestamped
8 minutes earlier — while tabs_context_mcp was still reporting it as available.
2. Only one Chrome window exists. Enumerating every top-level Chrome_WidgetWin_* window:
pid=21480 vis=True min=False rect=10,10,1050x652 title='Download Claude | Claude by Anthropic - Google Chrome'
13 chrome.exe processes, all from one launch, one --user-data-dir. No second instance, no
minimized or off-screen window that could host the phantom tab.
3. The phantom tab executes code. This is the core of the report. Against tab 342544959:
JSON.stringify({path: location.pathname, hidden: document.hidden,
w: window.outerWidth, h: window.outerHeight,
screenX: window.screenX, screenY: window.screenY})
returns:
{"path":"/login","hidden":true,"w":0,"h":0,"screenX":0,"screenY":0}
navigate to a new URL also reports success, and a subsequent javascript_tool call reflects the
new location.pathname — so the target is not a frozen snapshot; it is servicing navigations.
The w:0, h:0, screenX:0, screenY:0 signature is the only available tell, and it is ambiguous:
ordinary backgrounded tabs can report hidden: true, so an agent cannot use this to distinguish a
real background tab from a phantom one. I misdiagnosed it as a minimized window and sent the user
looking for a window that did not exist.
4. tabs_create_mcp inherits the fault. Creating a new tab in the group returns a new id
(342544960) that is equally invisible to the user and reports the same hidden/0x0 signature.
So the bug is not confined to the pre-existing stale entry — the group itself is anchored to
something detached from the visible browser.
Secondary issue: device registry name desync
list_connected_browsers returned a single browser named "Browser 1":
[{"deviceId":"95134706-b106-417c-aa5a-ba36df26f56d","name":"Browser 1","osPlatform":"Windows","isLocal":true}]
Calling select_browser with exactly that deviceId responded:
Connected to browser "Browser 2".
Earlier in the same session two browsers were listed, and 95134706-… was the one labeled
"Browser 2". The registry appears to retain stale device entries and reassign display names, which
makes the disambiguation prompt unreliable — the user cannot tell which browser they are selecting.
Impact
Beyond the wasted cycles, this blocks a common and important workflow: any site whose auth cannot
be handed to the agent.
The target site (College Board MyPractice) keeps its session in per-tab sessionStorage. Auth
therefore cannot be inherited from another tab — the specific tab the agent drives must be the one
the user signs into. When that tab is a phantom, there is no way for the user to authenticate it, and
no way for the agent to detect why. Related: #29523 notes that pre-authenticated tabs are invisible
to Claude because they belong to a prior tab group; combined, these two make agent-driven work on
authenticated sites effectively impossible once the group is in a bad state.
Nothing recovered the session: closing all browsers, reopening, re-pairing via switch_browser andselect_browser, closing the group's tabs, and creating new ones all returned to the same phantom
group.
Suggested fixes
- Validate tab liveness before returning it. Have
tabs_context_mcpconfirm each id against
chrome.tabs.query and drop entries that no longer resolve, rather than serving a cached list.
- Fail loudly on detached targets. If a tool call is dispatched to a tab that is not in the live
tab set, return an explicit error (tab no longer exists) instead of executing against a detached
target and returning success. Silent success is the most damaging part of this bug.
- Expose a liveness/visibility signal. Include something like
visible/windowId/activein
tabs_context_mcp output so an agent can tell a backgrounded tab from a detached one. Today
hidden: true is genuinely ambiguous.
- Provide a documented hard-reset for the extension's tab-group state. #34030 reports that
clearing Local Extension Settings, killing the native host, and rebooting all fail to clear it.
- Dedupe the device registry and stop reassigning display names, so
select_browserselects the
browser the user actually chose.
Related
- #34030 — stale/cached tab data across sessions (closed as not planned)
- #29523 — tab groups don't persist; pre-authenticated tabs invisible (closed as not planned)
- #21106 —
tabs_context_mcplists tabs but operations fail with "No tab available" - #31308 — MCP tab group dissolves when closing tabs
- #63934 — Windows grouping failure
The first two are closed as stale, but the underlying defect is still present and — per the
execution behavior documented above — worse than those reports characterize it.