Skip to content

fix(understudy): prune descendant frame ownership and cached frame wrappers on detach and close - #3441

Open
princejain756 wants to merge 1 commit into
browserbase:mainfrom
princejain756:fix/nested-frame-ownership-and-page-close-cleanup
Open

princejain756 wants to merge 1 commit into
browserbase:mainfrom
princejain756:fix/nested-frame-ownership-and-page-close-cleanup

Conversation

@princejain756

@princejain756 princejain756 commented Nov 11, 2026 •

Copy link
Copy Markdown

Why

Closing a page or detaching a frame subtree in BrowserContext left child frame entries in frameOwnerPage and retained cached Frame wrappers, accumulating stale references across repeated page opens and closes (#3240). Process-swap detaches could also remove frames before their replacement session took ownership.

What changed

  • In FrameRegistry, collect and return all detached subtree frame IDs, track swapping state during process swaps so topology is preserved until the replacement session attaches, and clean up session frames in detachSession.
  • In Page, invalidate WebMCP state, frame cache, and frame ordinals for the detached frame and all its descendants. In dispose(), clear event disposers and caches safely even if individual disposers throw.
  • In BrowserContext, sync frame ownership during tree seeding, prune descendant frame entries from frameOwnerPage on detachment and page destruction, and dispose open pages during context shutdown.
  • Added 4 unit tests in understudy-context-oopif-adoption.test.ts covering 100-page nested-frame open/close cycles, subtree detach cleanup, process swaps, and resilient error recovery.

Test plan

  • pnpm exec vitest run packages/extension/tests/understudy-context-oopif-adoption.test.ts passes (23/23 tests, including 100 nested page open/close cycles leaving zero stale entries in frameOwnerPage).
  • pnpm exec vitest run packages/extension/tests/understudy-context-domain-policy.test.ts packages/extension/tests/page-webmcp-tools.test.ts packages/extension/tests/page-webmcp-invocations.test.ts packages/extension/tests/page-cdp-events.test.ts passes (89/89 tests).
  • pnpm -F @browserbasehq/stagehand-extension typecheck and oxfmt check pass with 0 errors.

Closes #3240


Summary by cubic

Fixes stale frame ownership and cached Frame wrappers accumulating in BrowserContext when pages close or frame subtrees detach, which piled up across repeated page open/close cycles (#3240). Process-swap detaches now keep frame topology intact until the replacement session takes ownership.

  • FrameRegistry returns all detached subtree frame IDs, tracks mid-swap frames, and prunes session-owned frames in detachSession.
  • Page invalidates WebMCP state, frame cache, and frame ordinals for the whole detached subtree; dispose() clears caches and disposers safely even if an individual disposer throws.
  • BrowserContext syncs frame ownership during tree seeding, prunes descendant entries from frameOwnerPage on detach and page destruction, and disposes open pages during context shutdown.
  • Added 4 unit tests covering 100 nested-frame open/close cycles, subtree detach cleanup, process swaps, and close-time error recovery.

Closes #3240.

Written for commit e943c38. Summary will update on new commits.

View guided diff

@changeset-bot

changeset-bot Bot commented Nov 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e943c38

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@browserbasehq/stagehand-extension Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

This PR is from an external contributor and must be approved by a stagehand team member with write access before CI can run.
Approving the latest commit mirrors it into an internal PR owned by the approver.
If new commits are pushed later, the internal PR stays open but is marked stale until someone approves the latest external commit and refreshes it.

@github-actions github-actions Bot added external-contributor Tracks PRs mirrored from external contributor forks. external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. labels Nov 11, 2026

This branch has not been deployed

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

Labels

external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. external-contributor Tracks PRs mirrored from external contributor forks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Closing pages with nested frames leaves stale frame ownership references

1 participant