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
- Set mode to 1 for Parcel resolution semantics or 2 for Node resolution semantics.
- Use a named constant to avoid magic numbers: const MODE = { PARCEL: 1, NODE: 2 }.
- If loading options from JSON, coerce mode with Number(mode) and validate it is 1 or 2 before constructing.
- 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
- Use a named constant (PARCEL=1, NODE=2) instead of magic numbers.
- Validate mode immediately after loading config from JSON, where it may arrive as a string.
- Keep the JsResolverOptions field name 'mode' in mind — typos like 'resolverMode' silently leave mode at 0.
- Assert the Resolver construction in a unit test to catch config drift.
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
- GenericFailure
- Resolvers must return an absolute path, ${resolver.name} ret
- NodeFS isn't available in the browser
- Please provide a worker path!
- Invalid backend: ${backend}
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/08a734d23724ad3c.
Report an issue: GitHub.