Skip to content

[v2]: handle target closed errors on popups - #1710

Merged
seanmcguire12 merged 2 commits into
v2from
handle-target-closed-errors-on-popups
Feb 19, 2026
Merged

[v2]: handle target closed errors on popups#1710
seanmcguire12 merged 2 commits into
v2from
handle-target-closed-errors-on-popups

Conversation

@seanmcguire12

@seanmcguire12 seanmcguire12 commented Feb 19, 2026

Copy link
Copy Markdown
Member

why

  • some popups close so quickly that Stagehand tries to attach a CDP session after the target is already gone, which produces unhandled Target.attachToTarget / newCDPSession errors
  • in the case of fast‑closing popups during auto‑init, we want to treat “target gone” as a benign race instead of surfacing as failures

what changed

  • added shared “target gone” helpers in lib/utils.ts
  • guarded CDP session creation to throw a targeted error when the page/frame is already closed or detached
  • swallowed that targeted error during page initialization and frame listener attach only when the target is closed or the error indicates the target is gone, so other CDP failures still surface

Summary by cubic

Handle rapidly opening/closing popups by detecting “target gone” scenarios and preventing CDP session attach errors. This reduces flakiness during auto-init and keeps fast-closing popups from surfacing as failures.

  • Bug Fixes
    • Added StagehandTargetClosedError and utils to detect closed/detached targets and CDP “target gone” errors.
    • Guarded CDP session creation and frame listener attach; swallow only “target closed” errors during init.
    • Removed cached CDP clients when targets are gone and skipped work on already-closed pages/frames.

Written for commit 6143b9c. Summary will update on new commits. Review in cubic

@changeset-bot

changeset-bot Bot commented Feb 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6143b9c

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

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

@greptile-apps

greptile-apps Bot commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR addresses race conditions with fast-closing popups by adding graceful error handling for CDP session attachment failures.

Key Changes:

  • Added utility functions (isTargetGoneError, isTargetGone) to detect closed/detached targets
  • Introduced StagehandTargetClosedError for targeted error handling
  • Protected page initialization in StagehandContext.init() with try-catch blocks that swallow target-gone errors
  • Guarded CDP session creation in getCDPClient() and attachFrameNavigatedListener() to check if targets are closed before and after operations
  • All defensive checks treat target-closed scenarios as benign during auto-initialization while preserving other CDP errors

The implementation correctly handles the race condition where popups close before Stagehand can attach CDP sessions, treating these as expected outcomes rather than failures.

Confidence Score: 5/5

  • Safe to merge - well-designed defensive error handling with no breaking changes
  • The PR implements robust error handling for a specific race condition without introducing breaking changes or security issues. The code follows existing patterns, adds appropriate error types, and correctly distinguishes between expected target-closed scenarios and genuine errors that should surface.
  • No files require special attention

Important Files Changed

Filename Overview
.changeset/humble-terms-wink.md Standard changeset file documenting the patch-level fix for popup target closed errors
lib/utils.ts Added helper functions isTargetGoneError and isTargetGone to detect closed/detached targets
types/stagehandErrors.ts Added StagehandTargetClosedError class with optional causedBy field for chaining underlying errors
lib/StagehandContext.ts Added defensive checks and graceful error handling for closed pages during initialization and CDP session creation
lib/StagehandPage.ts Enhanced getCDPClient to check target status before and after CDP operations and throw appropriate errors

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Popup Opens] --> B{Page Already Closed?}
    B -->|Yes| C[Skip Initialization]
    B -->|No| D[Create StagehandPage]
    
    D --> E{Page Closed During Init?}
    E -->|Yes - StagehandTargetClosedError| F[Catch and Continue]
    E -->|Yes - isTargetGoneError| F
    E -->|Yes - page.isClosed| F
    E -->|No| G[Page Initialized]
    
    G --> H[Attach CDP Session]
    H --> I{Target Still Available?}
    I -->|No| J[Return Early]
    I -->|Yes| K[Create CDP Session]
    
    K --> L{CDP Session Created?}
    L -->|Error - Target Gone| M[Catch and Return]
    L -->|Error - Other| N[Re-throw Error]
    L -->|Success| O[Session Attached]
    
    F --> P[Continue Without Page]
    M --> P
    P --> Q[Normal Operation]
    O --> Q
Loading

Last reviewed commit: 6143b9c

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant B as Browser (Playwright)
    participant C as StagehandContext
    participant P as StagehandPage
    participant U as Utils

    Note over B,U: Initialization / New Popup Detected

    C->>B: Detect new page/popup
    
    C->>B: NEW: page.isClosed()
    alt Page is already gone
        C-->>C: Skip initialization
    else Page active
        C->>P: createStagehandPage(pwPage)
        
        P->>U: NEW: isTargetGone(pwPage)
        U-->>P: false

        P->>C: getCDPSession()
        
        C->>B: Playwright: newCDPSession()
        
        alt CHANGED: Race Condition (Popup closes during attach)
            B-->>C: Error ("Target closed" / "No target with id")
            C-->>P: Error
            P->>U: NEW: isTargetGoneError(err)
            U-->>P: true
            P-->>C: Throw StagehandTargetClosedError
            
            Note over C: NEW: Catch/Swallow during Init
            C->>C: Log & Continue (Treat as benign)
        else Success Path
            B-->>C: CDPSession
            C-->>P: CDPSession
            P->>P: Cache CDPSession
            P-->>C: StagehandPage instance
        end
    end

    Note over B,U: Subsequent Page Operations

    P->>P: getCDPSession()
    P->>U: NEW: Check cache & isTargetGone()
    opt NEW: Target gone but session was cached
        P->>P: Remove from cdpClients cache
        P-->>C: Throw StagehandTargetClosedError
    end

    C->>B: CHANGED: attachFrameNavigatedListener(pwPage)
    alt NEW: Page closes before listener attach
        C->>B: pwPage.newCDPSession()
        B-->>C: Error (Target gone)
        C->>U: isTargetGoneError(err)
        U-->>C: true
        C-->>C: Gracefully exit listener setup
    end
Loading

@seanmcguire12
seanmcguire12 merged commit df76207 into v2 Feb 19, 2026
15 of 16 checks passed
@github-actions github-actions Bot mentioned this pull request Feb 19, 2026
seanmcguire12 pushed a commit that referenced this pull request Feb 19, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to v2, this PR will
be updated.


# Releases
## @browserbasehq/stagehand@2.5.8

### Patch Changes

- [#1710](#1710)
[`df76207`](df76207)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - handle
target closed errors on rapidly opening/closing popups

## @browserbasehq/stagehand-evals@1.1.8

### Patch Changes

- Updated dependencies
\[[`df76207`](df76207)]:
    -   @browserbasehq/stagehand@2.5.8

## @browserbasehq/stagehand-examples@1.0.17

### Patch Changes

- Updated dependencies
\[[`df76207`](df76207)]:
    -   @browserbasehq/stagehand@2.5.8


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Publish Stagehand 2.5.8 with a fix for “target closed” errors when
popups are opened and closed quickly, improving stability. Updated evals
(1.1.8) and examples (1.0.17) to depend on this patch.

<sup>Written for commit fb39851.
Summary will update on new commits. <a
href="https://cubic.dev/pr/browserbase/stagehand/pull/1714">Review in
cubic</a></sup>

<!-- End of auto-generated description by cubic. -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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