Skip to content

Non-discarded tab with abnormal state causes target.asPage() to hang indefinitely, blocking browser.pages() #1918

@so2bin

Description

@so2bin

Related

#1230, #775

Description

I encountered a variant of the Network.enable timed out issue that has a different root cause than frozen/discarded tabs described in #1230.

In my setup, a specific tab (https://so2bin.github.io/) caused browser.pages() to hang indefinitely, but:

  1. The tab was NOT frozen or discarded — it was a normal open tab.
    1. Direct CDP Network.enable worked fine on ALL tabs including the problematic one (sub-millisecond response).
    1. Puppeteer's target.asPage() was the operation that hung — not Network.enable itself.
    1. Refreshing the tab in the browser resolved the issue — suggesting the tab was in some transient abnormal state.
      This means the Chromium-level fix for discarded tabs (https://crrev.com/c/7772775) would NOT address this variant.

Reproduction

  1. Connect to Edge browser (Edg/147.0.3912.60) via --browserUrl=http://localhost:9222 from WSL2.
    1. Have ~13 page tabs open, including one tab in an abnormal state.
    1. Call list_pages or any MCP tool that triggers browser.pages().
    1. Observe: the MCP server hangs during initialization and never responds.

Diagnostic Evidence

Step 1: Direct CDP works perfectly on all tabs

Connecting via raw WebSocket to the browser endpoint and manually calling Target.attachToTarget + Network.enable on each of the 13 page targets — all succeed in 0–2ms:

OK  sre / klink-stress / ko-specs-scan · Git  attach=1ms  Network.enable=1ms
OK  KO服务指标面板 - ko - Dashboards - Grafana    attach=1ms  Network.enable=1ms
OK  Tag管理                                   attach=1ms  Network.enable=1ms
...(all 13 pages OK, total 181ms)

Step 2: Puppeteer connect() succeeds, but pages() hangs

const browser = await puppeteer.connect({ browserURL: 'http://localhost:9222' });
// OK in 48ms
const pages = await browser.pages();
// Never returns — hangs indefinitely

Step 3: Isolating the problematic target

Testing target.asPage() individually on each page target:

[0] https://so2bin.github.io/  ... FAIL 6005ms: TIMEOUT  ← ONLY this one hangs
[1] https://fs.dig.kso.net/...  ... OK 7ms
[2] https://sre.kso.net/...     ... OK 3ms
...(all other 13 pages OK in 2-16ms)

Step 4: Refreshing the tab fixes everything

After manually refreshing the so2bin.github.io tab in Edge, browser.pages() and all MCP tools work perfectly.

Key Difference from #1230

#1230 (frozen/discarded) This issue
Tab state Frozen/discarded by memory saver Normal open tab, not discarded
Network.enable via raw CDP Times out Works fine (sub-ms)
Hanging operation Network.enable in Puppeteer target.asPage() in Puppeteer
Browser Chrome on macOS Edge on Windows (via WSL2)
Fix Target.activateTarget or Chromium patch Refresh the tab

Suggested Fix

Since browser.pages() is a blocking all-or-nothing call, a single problematic target blocks the entire MCP server. I suggest:

  1. Per-target timeout in pages() enumeration — if asPage() doesn't complete within N seconds for a target, skip it and continue with the remaining targets.
    1. Lazy page initialization — don't eagerly call asPage() on all targets during initialization. Only initialize pages on demand when a tool actually needs them.
      This would make chrome-devtools-mcp robust against any type of abnormal tab state, not just the frozen/discarded case.

Environment

  • chrome-devtools-mcp version: 0.20.3 and 0.21.0 (both affected)
    • Browser: Microsoft Edge 147.0.3912.60 (Windows)
      • Puppeteer: 24.40.0 (bundled)
        • Node: v22.18.0
          • OS: WSL2 (Ubuntu) connecting to Windows Edge
            • Connection: --browserUrl=http://localhost:9222

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions