From 20dc90fde5c049e7f1996a3b23d6b9c36bd724d0 Mon Sep 17 00:00:00 2001 From: Max B Date: Sat, 22 Aug 2026 11:16:53 +0200 Subject: [PATCH] fix(compiler): cap rendered diagnostics to avoid RangeError on large reports renderAll() joined every diagnostic's rendered text (each with its own source-line context) into one string with no size limit. On programs with thousands of diagnostics, the joined string exceeds V8's max string length and the whole report crashes with an uncatchable-feeling RangeError instead of showing anything, including diagnostics that would have fit. Cap the render at 1000 diagnostics and note how many were omitted. --- packages/compiler/src/diagnostics/render.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/compiler/src/diagnostics/render.ts b/packages/compiler/src/diagnostics/render.ts index 772618049..b79fb881f 100644 --- a/packages/compiler/src/diagnostics/render.ts +++ b/packages/compiler/src/diagnostics/render.ts @@ -82,6 +82,12 @@ export function renderDiagnostic( return out.join("\n"); } +// Above this many diagnostics, rendering every one (each carrying its own +// source-line context) can push the joined report past V8's max string +// length (RangeError: Invalid string length) — cap the render and say so, +// rather than crashing the whole report. +const MAX_RENDERED_DIAGNOSTICS = 1000; + export function renderAll( diags: ScrDiagnostic[], sourceTextByFile: Map, @@ -90,10 +96,15 @@ export function renderAll( const sorted = [...diags].sort( (a, b) => a.loc.file.localeCompare(b.loc.file) || a.loc.start - b.loc.start, ); - return sorted + const shown = sorted.slice(0, MAX_RENDERED_DIAGNOSTICS); + const rendered = shown .map((d) => { const text = sourceTextByFile.get(d.loc.file); return renderDiagnostic(d, text === undefined ? undefined : { text }, opts); }) .join("\n\n"); + const omitted = sorted.length - shown.length; + return omitted > 0 + ? `${rendered}\n\n... ${omitted} more diagnostic${omitted === 1 ? "" : "s"} not shown (${sorted.length} total)` + : rendered; }