swc-project/swc · error

failed to handle: {s}

Error message

failed to handle: {s}

What it means

The Node minifier binding (bindings/binding_minifier_node/src/util.rs `try_with`) wraps each operation in catch_unwind under GLOBALS; a panic with a String payload becomes 'failed to handle: {s}' and is returned as a pretty error. This is the napi @swc/minifier surface: the JS minifier (compressor/mangler/printer) panicked instead of returning Err.

Source

Thrown at bindings/binding_minifier_node/src/util.rs:48

    GLOBALS
        .set(&Default::default(), || {
            try_with_handler(
                cm,
                swc_error_reporters::handler::HandlerOpts {
                    skip_filename,
                    ..Default::default()
                },
                |handler| {
                    //
                    let result = catch_unwind(AssertUnwindSafe(|| op(handler)));

                    let p = match result {
                        Ok(v) => return v,
                        Err(v) => v,
                    };

                    if let Some(s) = p.downcast_ref::<String>() {
                        Err(anyhow!("failed to handle: {s}"))
                    } else if let Some(s) = p.downcast_ref::<&str>() {
                        Err(anyhow!("failed to handle: {s}"))
                    } else {
                        Err(anyhow!("failed to handle with unknown panic message"))
                    }
                },
            )
        })
        .map_err(|e| e.to_pretty_error())
}

// This was originally under swc_nodejs_common, but this is not a public
// interface for the custom binary - they should choose own trace initialization
// instead. Will keep as hidden for now until there's proper usecase.

/// Deprecated no-op kept for compatibility with existing binding entrypoints.
pub fn init_default_trace_subscriber() {}

View on GitHub (pinned to d7d7434666)

Solutions

  1. Read {s} - it identifies the panicking assertion inside the minifier
  2. Toggle minify options to isolate the pass (compress: false, then mangle: false, then individual compress toggles) and minimize the JS repro
  3. Upgrade (or if newly broken, pin/roll back) @swc/minifier - panics are fixed frequently
  4. Report the reproducible case to the swc repo with the option set and input

Example fix

// before
const out = minify(code, { compress: true, mangle: true });

// after: bisect which pass panics
const out = minify(code, { compress: false, mangle: true }); // still panics? -> mangler
const out2 = minify(code, { compress: true, mangle: false }); // -> compressor
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const out = minify(code, minifyOpts);
} catch (e) {
  const msg = String(e);
  if (msg.startsWith('failed to handle:')) {
    // internal minifier panic: capture code + opts, fall back to unminified or mangle-only
    return { code, panic: msg };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling minify() from @swc/minifier (napi) on JavaScript whose compression/mangling path panics - known edge cases in swc_ecma_minifier for specific versions (inliner, mangler, or DCE invariants on unusual AST shapes produced by modern syntax).

Common situations: CI minification of large bundles failing on one chunk after a dependency or @swc/minifier upgrade; production builds with compress/mangle enabled hitting a version-specific panic; usually resolves by pinning or bumping the package.

Related errors


AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16). Data as JSON: /api/errors/6c5b935555e3e76e. Report an issue: GitHub.