denoland/deno · error

esbuild exited before the rebuild completed

Error message

esbuild exited before the rebuild completed

What it means

In `deno bundle --watch`, after sending a rebuild request Deno waits on esbuild's rebuild-complete event over a channel. If that channel closes instead of yielding a response, the esbuild child process exited (crashed or was killed) before finishing the rebuild, and watch mode surfaces this error.

Solutions

  1. Re-run the bundle — the next start respawns the esbuild service cleanly
  2. Check `dmesg`/journalctl for an OOM kill of esbuild; free memory or split the bundle to reduce peak usage
  3. Update deno (bundled esbuild fixes land often); if esbuild panicked, capture its stderr and report the repro
Defensive patterns

Strategy: retry

Try / catch

In watch/build scripts, catch this error, treat the esbuild service as dead, and restart the bundling task (bounded retries with backoff) rather than propagating immediately.

Prevention

When it happens

Trigger: A watch-mode rebuild during which the esbuild service dies: OOM kill, manual kill of the esbuild process, an esbuild panic on pathological input, or system shutdown mid-rebuild.

Common situations: Memory-constrained dev machines or CI where esbuild gets OOM-killed on large rebuilds; stray process cleanup scripts killing esbuild children.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/fba65545d4173b5b. Report an issue: GitHub.

Appendix: source

Thrown at cli/tools/bundle/mod.rs:1185

    Ok(response)
  }

  async fn rebuild(&mut self) -> Result<BuildResponse, AnyError> {
    match self.mode {
      BundlingMode::OneShot => {
        panic!("rebuild not supported for one-shot mode")
      }
      BundlingMode::Watch => {
        log::trace!("sending rebuild request");
        let _response = self
          .client
          .send_rebuild_request(0)
          .await
          .context("failed to send rebuild request to esbuild")?
          .map_err(|e| message_to_error(&e, &self.cwd))?;
        let response = self.on_end_rx.recv().await.ok_or_else(|| {
          deno_core::anyhow::anyhow!(
            "esbuild exited before the rebuild completed"
          )
        })?;
        Ok(response.into())
      }
    }
  }

  async fn reload_specifiers(
    &mut self,
    changed_paths: &[PathBuf],
  ) -> Result<(), AnyError> {
    self.reload_html_entrypoints(changed_paths)?;
    self.plugin_handler.reload_specifiers(changed_paths).await?;
    Ok(())
  }

  fn reload_html_entrypoints(

View on GitHub (pinned to 9ad36f7a2c)