Skip to content

fix: manage third-party element handle lifetimes - #2452

Open
haopengmai wants to merge 2 commits into
ChromeDevTools:mainfrom
haopengmai:fix/retain-third-party-element-handles
Open

fix: manage third-party element handle lifetimes#2452
haopengmai wants to merge 2 commits into
ChromeDevTools:mainfrom
haopengmai:fix/retain-third-party-element-handles

Conversation

@haopengmai

Copy link
Copy Markdown

Summary

  • scope third-party tool input handles to a single execution
  • transfer returned element handles to McpPage only after a snapshot succeeds
  • release retained handles on replacement, main-frame navigation, and page teardown
  • return a fresh caller-owned handle for every UID lookup
  • keep the page-side element stash invocation-local and clear it on success and failure

Root cause

TextSnapshot stored third-party element handles in snapshot nodes while also mutating McpPage.extraHandles implicitly. The explicit resource-management change in #2443 then disposed those handles as soon as snapshot creation completed, so UIDs for elements outside the accessibility tree immediately referenced disposed handles.

The page-side stash also accumulated elements across tool calls, and retained handles were not invalidated on navigation or protected against teardown races.

This change makes ownership explicit:

  • tool input handles are temporary
  • McpPage owns retained output anchors
  • TextSnapshot only consumes anchors and mints a fresh handle per lookup
  • browser-side stashes are temporary handoff storage

User impact

UIDs returned by third-party developer tools remain reusable across subsequent tool calls, including detached or otherwise non-accessible DOM elements. Old resources are released deterministically instead of leaking or surviving navigation and teardown.

Tests

  • npm run check-format
  • PUPPETEER_EXECUTABLE_PATH='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' npm run test tests/tools/thirdPartyDeveloper.test.ts
  • PUPPETEER_EXECUTABLE_PATH='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' npm run test tests/McpPage.test.ts tests/McpContext.test.ts tests/PageCollector.test.ts tests/TextSnapshot.test.ts tests/tools/input.test.ts tests/tools/script.test.ts tests/tools/snapshot.test.ts tests/tools/thirdPartyDeveloper.test.ts

@google-cla

google-cla Bot commented Jul 31, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@haopengmai
haopengmai force-pushed the fix/retain-third-party-element-handles branch from 2314a34 to 7a64f97 Compare July 31, 2026 06:48
@haopengmai
haopengmai marked this pull request as ready for review July 31, 2026 06:49
@OrKoN
OrKoN requested review from Lightning00Blade and wolfib July 31, 2026 09:55
@OrKoN

OrKoN commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

@Lightning00Blade could be a regression from the using PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants