swc-project/swc · error · anyhow::Error

failed to parse options: {}

Error message

failed to parse options: {}

What it means

Generated by the build_minify_sync wasm macro (crates/binding_macros/src/wasm.rs), used by @swc/wasm-minifier / wasm minify entry points. The non-null `opts` JsValue failed serde_wasm_bindgen::from_value deserialization into the minify options struct. null/undefined take the Default path, so this error only occurs when a real value was passed whose shape does not match the Rust struct for the shipped version.

Source

Thrown at crates/binding_macros/src/wasm.rs:115

    build_minify_sync!($(#[$m])*, Default::default());
  };
  ($(#[$m:meta])*, $opt: expr) => {
    $(#[$m])*
    pub fn minify_sync(s: $crate::wasm::js_sys::JsString, opts: $crate::wasm::JsValue) -> Result<$crate::wasm::JsValue, $crate::wasm::JsValue> {
      use serde::Serialize;

      let c = $crate::wasm::compiler();

      $crate::wasm::try_with_handler_globals(
          c.cm.clone(),
          $opt,
          |handler| {
              c.run(|| {
                  let opts = if opts.is_null() || opts.is_undefined() {
                      Default::default()
                  } else {
                    $crate::wasm::serde_wasm_bindgen::from_value(opts)
                      .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))?
                  };

                  let fm = c.cm.new_source_file($crate::wasm::FileName::Anon.into(), String::from(s));
                  let program = $crate::wasm::anyhow::Context::context(c.minify(fm, handler, &opts, Default::default()), "failed to minify file")?;

                  program
                    .serialize($crate::wasm::compat_serializer().as_ref())
                    .map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
              })
          },
      )
      .map_err(|e| $crate::wasm::convert_err(e, None))
    }
  };
}

/// Currently this relies on existence of minify_sync.
#[macro_export]

View on GitHub (pinned to d7d7434666)

Solutions

  1. Match the MinifyOptions interface shipped with your exact binding version (check its .d.ts); fix wrong-typed fields like compress/mangle booleans
  2. Pass null/undefined (or omit the argument) to run with defaults and confirm the call works, then add options back one by one to find the offending field
  3. Remove fields the Rust struct does not expect rather than relying on ignore behavior for enums/nested objects
  4. Align versions: reinstall the wasm package so the JS typings and the compiled Rust struct match

Example fix

// before
minifySync(src, { compress: 'true', mangle: 'true' });

// after
minifySync(src, { compress: true, mangle: true });
Defensive patterns

Strategy: validation

Validate before calling

// Validate against the shape before calling the wasm API
function checkMinifyOptions(o) {
  const errors = [];
  if ('compress' in o && typeof o.compress !== 'boolean' && typeof o.compress !== 'object')
    errors.push('compress must be boolean or object');
  if ('mangle' in o && typeof o.mangle !== 'boolean' && typeof o.mangle !== 'object')
    errors.push('mangle must be boolean or object');
  if ('module' in o && typeof o.module !== 'boolean')
    errors.push('module must be boolean');
  return errors;
}
const errs = checkMinifyOptions(opts);
if (errs.length) throw new TypeError errs.join('; ');

Type guard

function isMinifyOptions(v) {
  if (v == null) return true; // null/undefined -> defaults
  if (typeof v !== 'object' || Array.isArray(v)) return false;
  const c = v.compress;
  const m = v.mangle;
  return (c === undefined || typeof c === 'boolean' || typeof c === 'object') &&
         (m === undefined || typeof m === 'boolean' || typeof m === 'object');
}

Try / catch

try {
  const out = minifySync(src, opts);
} catch (e) {
  if (String(e).startsWith('failed to parse options')) {
    // e names the offending field via the serde detail; fix the shape and retry
    throw new TypeError Invalid swc minify options: ${e});
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a minify options object with wrong field types (compress: 'true' instead of boolean/object, mangle as a string, format fields nested incorrectly); passing a JSON string instead of an object; using options from a newer/older @swc/core version whose Rust struct in this wasm build does not have those fields/variants (enum value mismatch, e.g. an unknown module config value).

Common situations: Version skew between the JS-side typings and the wasm binary after a partial upgrade; copy-pasted options from other bundler docs (terserweboptions style) into swc minify; typos that change the JSON type.

Understand the failure class

Related errors


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