Version
playwright-core 1.64.0-next, source baseline 4302dbb.
Steps to reproduce
This is a follow-up to #41397, which was closed as outside Playwright's scope because its reproducer explicitly enabled prerendering. I encountered the same ID mismatch when attaching to an existing user-managed Chrome, without adding those prerendering flags. I am opening this to ask whether that existing-browser attachment scenario can be supported; I am not claiming a different root cause.
The original workflow was Chrome's remote debugging enabled through chrome://inspect/#remote-debugging, with Playwright MCP connecting to ws://127.0.0.1:9222/devtools/browser. One existing tab had a page target ID different from the root frame ID returned by Page.getFrameTree. Listing tabs stalled. I have not isolated the browser event that originally made the IDs diverge, so connecting to an arbitrary fresh Chrome session is not a deterministic reproducer.
A focused, deterministic regression case is available in this repository commit, in tests/library/chromium/connect-over-cdp.spec.ts, named should attach when the page target id differs from the main frame id.
The test uses Playwright's existing library harness. It rewrites only the page's targetId through a CDP transport adapter, leaving the real frame IDs and execution-context metadata unchanged. This isolates the ID assumption without enabling prerendering. It is a synthetic regression case, not a reproduction of the original browser event.
In a fresh checkout:
git clone --branch fix/preserve-user-focus https://github.com/humdrum00001010/playwright.git playwright-cdp-repro
cd playwright-cdp-repro
git checkout 756538c66b72387f8a1e7aa2b795a78489022f6d
npm ci
npm run build
npx playwright install chromium
To exercise the existing behavior while retaining the regression test, restore only the Chromium implementation to its parent revision, then rebuild and run the test:
git restore --source=756538c^ -- packages/playwright-core/src/server/chromium/crPage.ts
npm run build
npm run ctest -- connect-over-cdp.spec.ts --grep 'page target id differs'
The workaround is available for comparison by restoring that same file from 756538c, rebuilding, and rerunning the test. The branch also contains a separate focus-related customization; that is not the subject of this report or a request to upstream the whole branch.
Expected behavior
When attaching to an existing Chrome page, resolve its main-frame session even when the target ID differs from the main-frame ID. Page URL, title, evaluation, and DOM interactions should work.
Actual behavior
CRPage._sessions is keyed by target ID, but _sessionForFrame searches using the frame ID. For the affected root frame, there is no matching session and no parent, so it throws Frame has been detached.
In the observed live connection, CDP returned the real frame tree and URL, but Playwright's page URL remained empty and title/evaluation calls stalled. A single affected page therefore blocked MCP's all-pages title collection.
Additional context
The scope difference from #41397 is that connectOverCDP is attaching to a browser Playwright did not launch. Playwright's normal launch-time disabling of prerendering does not configure this already-running browser. The mismatch was observed directly; its original trigger remains unproven.
The linked workaround restored access to the affected live session. Its regression test covers attachment, DOM interaction, a child frame, a dialog, and reload. This is not a request to support arbitrary custom launch flags or to change MCP's focus behavior.
Per CONTRIBUTING.md, I am willing to work on an upstream fix and tests if this is approved for community contribution or assigned to me. I have not opened a PR and will wait for direction.
Environment
macOS 26.1 (25B78), Apple Silicon
Google Chrome 152.0.7977.83 (current installed version)
Node.js 26.7.0
npm 11.19.0
playwright-core 1.64.0-next, source baseline 4302dbb
Existing Chrome connection: ws://127.0.0.1:9222/devtools/browser
Version
playwright-core1.64.0-next, source baseline4302dbb.Steps to reproduce
This is a follow-up to #41397, which was closed as outside Playwright's scope because its reproducer explicitly enabled prerendering. I encountered the same ID mismatch when attaching to an existing user-managed Chrome, without adding those prerendering flags. I am opening this to ask whether that existing-browser attachment scenario can be supported; I am not claiming a different root cause.
The original workflow was Chrome's remote debugging enabled through
chrome://inspect/#remote-debugging, with Playwright MCP connecting tows://127.0.0.1:9222/devtools/browser. One existing tab had a page target ID different from the root frame ID returned byPage.getFrameTree. Listing tabs stalled. I have not isolated the browser event that originally made the IDs diverge, so connecting to an arbitrary fresh Chrome session is not a deterministic reproducer.A focused, deterministic regression case is available in this repository commit, in
tests/library/chromium/connect-over-cdp.spec.ts, namedshould attach when the page target id differs from the main frame id.The test uses Playwright's existing library harness. It rewrites only the page's
targetIdthrough a CDP transport adapter, leaving the real frame IDs and execution-context metadata unchanged. This isolates the ID assumption without enabling prerendering. It is a synthetic regression case, not a reproduction of the original browser event.In a fresh checkout:
git clone --branch fix/preserve-user-focus https://github.com/humdrum00001010/playwright.git playwright-cdp-repro cd playwright-cdp-repro git checkout 756538c66b72387f8a1e7aa2b795a78489022f6d npm ci npm run build npx playwright install chromiumTo exercise the existing behavior while retaining the regression test, restore only the Chromium implementation to its parent revision, then rebuild and run the test:
git restore --source=756538c^ -- packages/playwright-core/src/server/chromium/crPage.ts npm run build npm run ctest -- connect-over-cdp.spec.ts --grep 'page target id differs'The workaround is available for comparison by restoring that same file from
756538c, rebuilding, and rerunning the test. The branch also contains a separate focus-related customization; that is not the subject of this report or a request to upstream the whole branch.Expected behavior
When attaching to an existing Chrome page, resolve its main-frame session even when the target ID differs from the main-frame ID. Page URL, title, evaluation, and DOM interactions should work.
Actual behavior
CRPage._sessionsis keyed by target ID, but_sessionForFramesearches using the frame ID. For the affected root frame, there is no matching session and no parent, so it throwsFrame has been detached.In the observed live connection, CDP returned the real frame tree and URL, but Playwright's page URL remained empty and title/evaluation calls stalled. A single affected page therefore blocked MCP's all-pages title collection.
Additional context
The scope difference from #41397 is that
connectOverCDPis attaching to a browser Playwright did not launch. Playwright's normal launch-time disabling of prerendering does not configure this already-running browser. The mismatch was observed directly; its original trigger remains unproven.The linked workaround restored access to the affected live session. Its regression test covers attachment, DOM interaction, a child frame, a dialog, and reload. This is not a request to support arbitrary custom launch flags or to change MCP's focus behavior.
Per CONTRIBUTING.md, I am willing to work on an upstream fix and tests if this is approved for community contribution or assigned to me. I have not opened a PR and will wait for direction.
Environment