Skip to content

Analyze_heapsnapshot_contexts reports "No live contexts with dead fields" for Chrome 154 snapshots that lack the scope metadata it needs #2972

Description

@coygeek

Description of the bug

On the main build, analyze_heapsnapshot_contexts returns "No live contexts with dead fields were found." for a heap snapshot taken from Chrome 154 stable even when the page retains 30 closure contexts that each hold a dead 80 kB array. The same page captured with Chrome Canary 157 yields all 30 contexts. Chrome 154 snapshots contain no scope_fields metadata and no scope_id edges, which the analysis needs, and the tool does not say so: its existing "Scripts without scope metadata could not be analyzed" note does not appear. Users on current stable Chrome get a confident false negative. The tool is not in a release yet: it was added by #2791 and is listed in the open 1.11.0 release pull request #2823.

Actual behavior

main build, one run per channel:

Chrome 154 stable:
## Heap Snapshot Data
### Context Analysis
Showing 0-0 of 0 (Page 1 of 1).
No live contexts with dead fields were found.

Chrome Canary 157:
### Context Analysis
Showing 1-2 of 30 (Page 1 of 15).
Next page: 1
#### Context @35461 in `http://127.0.0.1:<port>/deadctx.html` — 80.0 kB
Script @17017, ScopeInfo @35459, offsets 32-349, 2 context fields
- `bigDead` (Array @43861) — 80.0 kB
...

metadata check: stable  scope_fields=0  "scope_id"=0
                canary  scope_fields=1  "scope_id"=2

An earlier investigation pass on the same machine observed the same pair of results (stable empty, Canary 30 contexts).

Reproduction

  1. Serve this page locally as deadctx.html:
<!doctype html><title>Dead context</title>
<script>
window.kept = [];
function make(i) {
  const bigDead = new Array(20000).fill(i); // read only by the dropped closure
  const small = i;
  const dropped = () => bigDead.length;     // forces bigDead into the shared context
  const keep = () => small;                 // retained; keeps the shared context alive
  dropped.toString();
  return keep;
}
for (let i = 0; i < 30; i++) window.kept.push(make(i));
</script>
  1. With Chrome 154 stable, send:
{"name":"new_page","arguments":{"url":"http://127.0.0.1:<port>/deadctx.html"}}
{"name":"take_heapsnapshot","arguments":{"pageId":2,"filePath":"<workspace>/snaps/deadctx-stable.heapsnapshot"}}
{"name":"analyze_heapsnapshot_contexts","arguments":{"filePath":"<workspace>/snaps/deadctx-stable.heapsnapshot","pageSize":2}}
  1. Repeat with the server started with --channel canary and the file name deadctx-canary.heapsnapshot.
  2. Check each file for the metadata: head -c 3000 <file> | grep -c scope_fields and grep -o '"scope_id"' <file> | wc -l.

Expectation

The tool "Loads a memory heapsnapshot to identify and rank closure contexts holding dead captured fields—variables no remaining live closure can read." Its output format already has a way to report input it cannot analyze ("Scripts without scope metadata could not be analyzed:", src/formatters/HeapSnapshotFormatter.ts on the main build). For a snapshot without the required scope metadata, the tool should say that the snapshot cannot be analyzed (for example, that it needs a newer Chrome), not report that no dead fields exist; the tool description should also state any Chrome version requirement.

MCP configuration

--headless --isolated --no-usage-statistics --no-performance-crux unless the reproduction states otherwise (update checks disabled with CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS=1).

Chrome DevTools MCP version

1.10.1 (npm) and main 5ddb0a3 (local build)

Chrome version

154.0.8037.98 (stable)

Node version

v22.23.2

Operating system

macOS 27.0

Environment details

  • Upstream main at commit 5ddb0a3110c5059f8e5513e566196cce2a35c6d1 built from source (the main build); chrome-devtools-mcp 1.10.1 from npm does not have this tool.
  • Google Chrome 154.0.8037.98 (stable) and Google Chrome Canary 157.0.8088.0 (--channel canary), Node.js v22.23.2, macOS 27.
  • Server started with --isolated --headless --no-usage-statistics --no-performance-crux --memoryDebugging and CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS=1, driven by a minimal stdio MCP client whose workspace root contains <workspace>/snaps/.

Evidence

  • Expected source: analyze_heapsnapshot_contexts description in docs/tool-reference.md on the main build, and the "Scripts without scope metadata could not be analyzed" branch of formatContextAnalysis in src/formatters/HeapSnapshotFormatter.ts.
  • Failure source: my runs of the steps above on the main build with both Chrome channels, outputs quoted under Actual behavior; static breadcrumb: the analysis in third_party/devtools-frontend/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts reads meta.scope_fields ?? [] and the scope_id offset, so with no metadata no scopes are correlated and none are reported as unanalyzable.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Fix check

Run steps 1-2 with Chrome 154 stable. Failing: the result is "No live contexts with dead fields were found." with no other note. Passing: the result states that the snapshot lacks the scope metadata needed for this analysis (or otherwise that it could not be analyzed), and does not claim that no dead fields exist. Control: the Canary 157 snapshot still lists the 30 bigDead contexts, and a Canary 157 snapshot of a page without closures (for example <!doctype html><title>Plain</title><p>No tools here</p>, which has scope_fields metadata) still reports "No live contexts with dead fields were found.", as it did in the observed run.

Additional context

The full open and closed issue and pull request corpus was screened as of 2026-10-06; no issue covers this. The first Chrome version that emits scope_fields was not determined; only 154 (absent) and 157 (present) were tested. The analysis code is vendored from DevTools frontend, so the detection may belong there; the user-facing message is this tool's.

Activity

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

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