Skip to content
Latchkey

esbuild "The service was stopped" in CI

esbuild runs as a long-lived child process that the JS API talks to. "The service was stopped" means that process exited before the build finished, commonly because the OOM killer killed it or the parent process tore it down early.

What this error means

A programmatic build or a tool wrapping esbuild fails with "Error: The service was stopped", sometimes alongside an exit code 137 from the runner.

esbuild
Error: The service was stopped
    at /app/node_modules/esbuild/lib/main.js:1393:29
    at Socket.afterClose (/app/node_modules/esbuild/lib/main.js:710:28)

Common causes

The esbuild process was OOM killed

A large build exceeded the runner's memory, so the kernel killed the esbuild child; the parent then sees the service as stopped (often exit 137).

The process exited or stop() was called early

The script ended, or esbuild.stop() ran, before a pending build promise resolved, terminating the shared service.

How to fix it

Reduce memory pressure on the build

  1. Check for an exit code 137, which indicates an OOM kill.
  2. Lower concurrency or split the build so peak memory drops.
  3. Use a larger runner if the build genuinely needs more memory.
Terminal
# raise Node heap for the build process if needed
NODE_OPTIONS=--max-old-space-size=4096 node build.mjs

Await all builds before stopping the service

Ensure every build() promise resolves before the script exits or you call stop().

build.mjs
await Promise.all(tasks.map((t) => esbuild.build(t)));
esbuild.stop();

How to prevent it

  • Watch for exit 137 as a sign of OOM in CI.
  • Await every esbuild build before stopping the service.
  • Size the runner and concurrency to the build's memory needs.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →