swc-project/swc · error

failed to run esbuild

Error message

failed to run esbuild

What it means

dbg-swc's esbuild comparison spawns the esbuild binary directly (Command::new('esbuild'), not via npx) with --minify / --minify-syntax --minify-whitespace, and requires a zero exit; non-zero aborts with this message while esbuild's stderr is already on your terminal. Unlike the terser path, this requires esbuild to be on PATH. Failures are a missing binary, or esbuild rejecting the input file.

Source

Thrown at crates/dbg-swc/src/util/minifier.rs:126

}

pub fn get_esbuild_output(file: &Path, mangle: bool) -> Result<String> {
    wrap_task(|| {
        let mut cmd = Command::new("esbuild");
        cmd.stderr(Stdio::inherit());

        cmd.arg(file);

        if mangle {
            cmd.arg("--minify");
        } else {
            cmd.arg("--minify-syntax").arg("--minify-whitespace");
        }

        let output = cmd.output().context("failed to get output")?;

        if !output.status.success() {
            bail!("failed to run esbuild");
        }

        String::from_utf8(output.stdout).context("esbuild emitted non-utf8 string")
    })
    .with_context(|| format!("failed to get output of {} from esbuild", file.display()))
}

/// We target es5 while esbuild does not support it.
///
/// Due to the difference, reducer generates something useless
struct Normalizer {}

impl VisitMut for Normalizer {
    noop_visit_mut_type!(fail);

    fn visit_mut_prop(&mut self, p: &mut Prop) {
        p.visit_mut_children_with(self);

View on GitHub (pinned to 5176682b65)

Solutions

  1. Install esbuild globally (npm i -g esbuild) or ensure node_modules/.bin is on PATH
  2. Verify with 'esbuild --version' in the same shell
  3. Reproduce manually: esbuild <file> --minify-syntax --minify-whitespace
  4. Upgrade esbuild if it rejects input SWC considers valid

Example fix

# before
$ which esbuild   # empty - only a local devDependency
error: failed to run esbuild

# after
$ npm install -g esbuild
$ esbuild --version
0.23.0
$ dbg-swc es minifier ...
Defensive patterns

Strategy: validation

Validate before calling

use std::process::Command;

fn esbuild_on_path() -> bool {
    Command::new("esbuild")
        .arg("--version")
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false)
}

assert!(esbuild_on_path(), "install esbuild: npm i -g esbuild (must be on PATH, not just node_modules)");

Try / catch

match get_esbuild_output(&file, mangle) {
    Ok(out) => out,
    Err(e) if format!("{e:#}").contains("failed to run esbuild") => {
        eprintln!("skipping esbuild diff: {e:#}");
        swc_output.clone()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running dbg-swc minifier comparison on a machine without esbuild on PATH (binary not found usually surfaces as the earlier 'failed to get output' context error, while a found-but-failing esbuild exits non-zero here), or esbuild failing to parse the candidate input.

Common situations: esbuild installed only as a project devDependency (node_modules/.bin not on PATH) while the harness expects a global binary; version drift where esbuild rejects syntax SWC emitted; CI images that install terser but not esbuild.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/9295ad446bf57226. Report an issue: GitHub.