`performance_stop_trace` throws on traces over ~512 MB since the 1.2 GB buffer default
Description of the bug
performance_stop_trace throws Error: Cannot create a string longer than 0x1fffffe8 characters
on any trace whose decoded JSON passes V8's maximum string length of 536,870,888 characters, which
for trace JSON means essentially that many bytes – about 512 MB.
parseRawTraceBuffer() decodes the entire recording into one string before parsing it
(new TextDecoder().decode(buffer) in src/processors/PerformanceTrace.ts), so since #2614 set
bufferSize to 1.2 GB the buffer takes more than twice what that decode can hold. #2614 raised it
to keep longer recordings from overflowing the old 200 MB default, which stayed under the cap – so
the ceiling moved rather than lifted, from a trace truncated at overflow (#2499) to no analysis at
all.
That decode sits above the try that turns a parse failure into a TraceParseError, so instead
of There was an unexpected error parsing the trace: … the client gets the bare Node error, naming
neither the trace nor its size. A filePath is saved before the parse, so its save line still comes
back and the raw trace stays locatable – without one nothing of the recording survives.
Reproduction
heavy.html, forced reflow in a requestAnimationFrame loop:
<!doctype html>
<div id="host"></div>
<script>
const host = document.getElementById('host');
for (let i = 0; i < 200; i++) {
const node = document.createElement('div');
node.textContent = 'row ' + i;
host.appendChild(node);
}
const rows = [...host.children];
function thrash() {
for (let round = 0; round < 100; round++) {
for (const row of rows) {
row.style.width = (100 + (round % 50)) + 'px';
void row.offsetHeight;
}
}
requestAnimationFrame(thrash);
}
requestAnimationFrame(thrash);
</script>
navigate_pageto that fileperformance_start_tracewithreload: falseandautoStop: false- Wait 15 seconds
performance_stop_trace
The size is what decides it rather than the wait, so on slower hardware the wait has to go up – pass
a filePath and the saved file says where a run landed. On an M5 Pro five seconds records
373,928,200 bytes – 70% of the cap – and returns the usual summary and insights, fifteen seconds
records 1,110,091,776 bytes, about twice it, and throws.
Expectation
A default buffer that cannot record more than the tool can then read. Failing that, an error naming the size, so it is clear whether anything survived.
MCP configuration
Driven by a scripted stdio client, server started as `--isolated --no-usage-statistics --workspace
` – the workspace only so a `filePath` outside the OS temp dir validates, and it reproduces with and without `--headless`Chrome DevTools MCP version
1.9.0
Chrome version
153.0.8010.36, launched by the server
Coding agent version
None for the repro above, which runs from a scripted client. First hit from Claude Code in the Claude macOS app 1.49585.0
Model version
Claude Opus 5
Chat log
None
Node version
v24.19.0
Operating system
macOS
Source: ChromeDevTools/chrome-devtools-mcp