Missing external parser kills the server silently 5s after startup

Author: mattgodboltCreated Aug 22, 2026Updated Aug 22, 2026

When an external parser binary is missing, ExternalParserBase (lib/external-parsers/base.ts:51-57, duplicated in plain.ts:23-30) logs an error, schedules setTimeout(() => process.exit(1), 5000), and throws. The throw is caught by CompileHandler.create (lib/handlers/compile.ts:301), which relabels it Unable to stat <id> compiler binary — so it reads as ordinary discovery noise and folds into Failed to create N out of M compilers. Five seconds later the orphan timer fires and exits 1 with no output at all. Locally this looked like: full startup, Listening on http://localhost:10240/, banner, then Failed running './app.ts' from node's watch mode and nothing else. The real error was at log line 2223 of 2369, ~150 lines above hundreds of visually identical benign Unable to stat ... ENOENT warnings. (Trigger: rust.amazon.properties sets externalparser.exe=/usr/local/bin/asm-parser at file scope, and gcc 16.2.0 (#8998) added a gccrs that actually exists on dev boxes, so the parser finally gets constructed.)

The fail-fast is intentional and should stay — it stops us deploying with non-functional compilers. But the current mechanism is a wall-clock race: the timer starts during compiler discovery, so depending on how long the rest of startup takes, the process either never binds (clean failure, what we want) or binds, passes healthcheck, and exits 1 five seconds later (flapping instance, no message). I saw both outcomes on the same config. Suggested fix: record missing parsers instead of scheduling an exit, check deterministically in lib/app/main.ts after discoverCompilers and before startListening, log one summary naming every affected compiler and path, then exit non-zero there — keeping the flush delay but announcing it. Optionally make it non-fatal under appArgs.devMode so dev boxes running amazon configs aren't killed. Also worth fixing the misleading Unable to stat catch message, which is what made this hard to find.

Source: compiler-explorer/compiler-explorer