Repository navigation
browser run: compile errors report no line, column, or source #353
Description
Summary
A program that fails to compile inside browser run is reported without any line, column, or source context, and is prefixed with a message that points at async plumbing rather than at the program. A one-character quoting mistake becomes an unactionable failure.
Repro
webcmd --session <id> browser run --stdin --no-snapshot-diff <<'JS'
const a = 1;
const s = 'x'y';
return a;
JSActual:
✖ BROWSER_RUN_SYNTAX_ERROR: QuickJS promise rejected: expecting ';'
✖ Fix the browser-run JavaScript syntax and retry.
No position. On a real program this is unactionable — the case that surfaced this had a 2,361-character line and reported only invalid number literal.
Cause
src/browser/run/runner.ts compiles the program with new AsyncFunction(source) inside the Promise.race:
value = await Promise.race([new AsyncFunction(source)(), cancellation]);Two consequences:
- A compile failure surfaces as a rejected promise, so
quickjs-host.tsprefixes it withQuickJS promise rejected:. Readers chase heredocs,await, and shell quoting instead of the program. - The position is discarded. QuickJS does supply it — probing the sandbox directly returns
lineNumber,columnNumber, and a stack ofat <input>:4:14— butnormalizeExecutionErroruses only.message.
The hint (Fix the browser-run JavaScript syntax and retry) restates the error code and names no cause.
Impact
Measured in the internal task eval: agents given this error blamed shell interpolation, encoded data URLs, arrow syntax, and top-level await in turn. Two scenarios abandoned the supplied page entirely and rebuilt a substitute rather than fix a single quote. The underlying mistake in every case was the same — an unescaped ' inside a single-quoted string holding a URL or HTML.
Expected
✖ BROWSER_RUN_SYNTAX_ERROR: invalid number literal at line 1, column 1215
tput%3E%3Cscript%3Econst%20form%3Ddocument.querySelector('%23registration')%2Cdr
^
✖ Your program failed to compile; the browser was never touched. A common cause
is an unescaped quote when embedding a URL or HTML in a string literal — use
double quotes or a template literal for values that contain apostrophes.
Fix
Compile before racing, and turn a compile failure into a BROWSER_RUN_SYNTAX_ERROR carrying:
- the caller's own line and column —
new AsyncFunction(body)prepends two lines of wrapper, so subtract them - a windowed excerpt with a caret, so a 2,000-character line stays readable
- a hint naming the quoting cause
Also skip the host stage prefix in quickjs-host.ts#toError for errors that already carry a BROWSER_RUN_ code.
Note
src/browser/run/runner.test.ts imports MemorySnapshotBaselineStore twice, so the file fails to load and its 74 tests have never run. They pass once the duplicate is removed.
Activity
ankitranjan7 commentedon Aug 19, 2026
Fixed locally on
fix/browser-run-syntax-position(commit93702f9), not yet pushed. Related: #354, #355 — both surface through the same error path.