parcel-bundler/parcel · error · napi::Error

InvalidArg

InvalidArg

Error message

Invalid mode

What it means

Thrown by the Resolver constructor when options.mode is not 1 or 2. Mode 1 creates a Parcel-style resolver (resolve::parcel), mode 2 a Node-style resolver (resolve::node). Any other value — including the default 0, null, undefined, or a string — is rejected before any resolution work begins. The error is sharp and immediate, so it is one of the easiest to diagnose.

Source

Thrown at crates/node-bindings/src/resolver.rs:205

    };
    #[cfg(target_arch = "wasm32")]
    let fs = {
      let fsjs = options.fs.unwrap();
      Arc::new(JsFileSystem {
        read: FunctionRef::new(env, fsjs.read)?,
        kind: FunctionRef::new(env, fsjs.kind)?,
        read_link: FunctionRef::new(env, fsjs.read_link)?,
      })
    };

    let mut resolver = match options.mode {
      1 => {
        parcel_resolver::Resolver::parcel(Path::new(&project_root), parcel_resolver::Cache::new(fs))
      }
      2 => {
        parcel_resolver::Resolver::node(Path::new(&project_root), parcel_resolver::Cache::new(fs))
      }
      _ => return Err(napi::Error::new(napi::Status::InvalidArg, "Invalid mode")),
    };

    if let Some(include_node_modules) = options.include_node_modules {
      resolver.include_node_modules = Cow::Owned(match include_node_modules {
        Either3::A(b) => IncludeNodeModules::Bool(b),
        Either3::B(v) => IncludeNodeModules::Array(v),
        Either3::C(v) => IncludeNodeModules::Map(v),
      });
    }

    if let Some(conditions) = options.conditions {
      resolver.conditions = ExportsCondition::from_bits_truncate(conditions);
    }

    if let Some(entries) = options.entries {
      resolver.entries = Fields::from_bits_truncate(entries);
    }

View on GitHub (pinned to 59484858a1)

Solutions

  1. Set mode to 1 for Parcel resolution semantics or 2 for Node resolution semantics.
  2. Use a named constant to avoid magic numbers: const MODE = { PARCEL: 1, NODE: 2 }.
  3. If loading options from JSON, coerce mode with Number(mode) and validate it is 1 or 2 before constructing.
  4. Check for option-name typos against the JsResolverOptions struct (mode, not resolverMode).

Example fix

// before
new Resolver(root, { mode: 0 }); // throws InvalidArg: Invalid mode
// or
new Resolver(root, {}); // mode defaults to 0 → throws

// after
const RESOLVER_MODE = Object.freeze({ PARCEL: 1, NODE: 2 });
new Resolver(root, { mode: RESOLVER_MODE.PARCEL });
Defensive patterns

Strategy: validation

Validate before calling

const VALID_MODES = new Set([1, 2]);
function validateResolverMode(mode) {
  const n = Number(mode);
  if (!VALID_MODES.has(n)) {
    throw new Error(`Resolver mode must be 1 (parcel) or 2 (node), got: ${mode}`);
  }
  return n;
}
const safeMode = validateResolverMode(options.mode);
new Resolver(root, { ...options, mode: safeMode });

Type guard

function isValidResolverMode(mode) {
  return mode === 1 || mode === 2;
}

Prevention

When it happens

Trigger: Constructing new Resolver(root, { mode }) where mode is 0, 3, a string '1', undefined, or omitted entirely. Also fires if the option is misnamed (e.g. resolverMode instead of mode) so mode stays at its default of 0.

Common situations: Migrating from an older Resolver API where mode defaulted differently; passing a string instead of a number from JSON config; typo in the option key; spreading a config object that does not include mode.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/08a734d23724ad3c. Report an issue: GitHub.