Skip to content

fix(extension): re-issue waitForSelector when a navigation destroys its context - #2983

Open
arrufat wants to merge 1 commit into
browserbase:mainfrom
arrufat:fix/wait-for-selector-across-navigation
Open

arrufat wants to merge 1 commit into
browserbase:mainfrom
arrufat:fix/wait-for-selector-across-navigation

Conversation

@arrufat

@arrufat arrufat commented Sep 18, 2026 •

Copy link
Copy Markdown

Fixes #2982.

Why

page.waitForSelector() is typically issued right after the locator.click() that submits a form, so its wait is installed in the document about to be navigated away from. When the commit lands while Frame.waitInLocatorWorld is awaiting the wait handle, Chrome rejects the Runtime.callFunctionOn with -32000 Inspected target navigated or closed (V8 words it Execution context was destroyed). The existing context-loss retry only recognizes Cannot find context with specified id, so the wait failed instead of being re-issued in the new document.

With a local form target that answers after 100 ms this fails deterministically on Chrome 153; with a fast target it fails about 2 runs in 5. The standalone repro is in #2982.

What changed

packages/extension/understudy/frame.ts: waitInLocatorWorld treats both navigation-teardown messages as context loss, alongside Cannot find context with specified id. They go through the existing single retry, so the re-issued wait gets a fresh locator world and the time left on the shared Progress deadline. Anything else, a second loss, or an expired deadline still throw as before.

The retry stays scoped to the selector wait, which has no side effects. Frame.evaluate is unchanged, since replaying an arbitrary evaluate after it ran can duplicate side effects (#2751).

packages/extension/understudy/waitForSelector.test.ts: the awaited wait is rejected once with each teardown message; the wait is re-installed in the new locator context and resolves.

Rebased onto #3146, which moved selector waits to waitInLocatorWorld; the earlier version of this PR added a retry loop in Page.waitForSelector, which is no longer needed.

@changeset-bot

changeset-bot Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0d54c6

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

This PR includes changesets to release 18 packages
Name Type
@browserbasehq/stagehand-extension Patch
@browserbasehq/stagehand Patch
browse Patch
@browserbasehq/stagehand-integrations Patch
@browserbasehq/stagehand-integrations-example-eve-facade Patch
@browserbasehq/stagehand-integrations-example-pi-facade Patch
@browserbasehq/stagehand-integrations-claude-agent-sdk Patch
@browserbasehq/stagehand-integrations-example-claude-code-facade Patch
@browserbasehq/stagehand-integrations-codex-sdk Patch
@browserbasehq/stagehand-integrations-example-codex-facade Patch
@browserbasehq/stagehand-integrations-cursor-sdk Patch
@browserbasehq/stagehand-integrations-deepagents-sdk Patch
@browserbasehq/stagehand-integrations-eve-sdk Patch
@browserbasehq/stagehand-integrations-fx-sdk Patch
@browserbasehq/stagehand-integrations-mastra-sdk Patch
@browserbasehq/stagehand-integrations-example-mastra-facade Patch
@browserbasehq/stagehand-integrations-pi-sdk Patch
@browserbasehq/stagehand-integrations-example-vercel-ai-facade 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.

…ts context

A wait issued right after the action that triggers a navigation is pinned
to the outgoing document. When the navigation commits, Chrome rejects the
awaited wait with "Inspected target navigated or closed" or "Execution
context was destroyed", which waitInLocatorWorld did not recognize as
context loss, so the wait failed instead of being re-issued in the new
document. Treat both messages like "Cannot find context with specified id"
in the existing single retry.
@arrufat
arrufat force-pushed the fix/wait-for-selector-across-navigation branch from a0d54c6 to 7d2f75e Compare October 19, 2026 10:30
@arrufat

arrufat commented Oct 19, 2026

Copy link
Copy Markdown
Author

Could a maintainer approve the latest commit so CI can run? The previous runs expired waiting for approval.

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.

waitForSelector fails with "Inspected target navigated or closed" when the click-triggered navigation commits after the wait is issued

1 participant