denoland/deno · error · TypeError
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "options" argument must be of type object. Received ${actual} What it means
ChildProcess#spawn(options) is the internal spawn entry point in Deno's child_process polyfill, called after a ChildProcess instance is constructed. It requires `options` to be a non-null object; passing null, undefined, a string, or a primitive throws ERR_INVALID_ARG_TYPE before any field is read. User-facing spawn()/fork() build this object for you, so hitting this means the internal method was called directly or an option object was dropped along the way.
Source
Thrown at ext/node/polyfills/internal/child_process.ts:332
constructor() {
super();
// 'child_process' channel fires once per ChildProcess construction, before
// spawn(). cluster.fork() / cp.fork() / cp.spawn() all flow through here,
// so a single publish site covers every entry point.
if (childProcessChannel.hasSubscribers) {
childProcessChannel.publish({ process: this });
}
}
/**
* Internal spawn method used by Node.js internals.
* This is called after creating a ChildProcess instance.
*/
spawn(options) {
// Validate options
if (options == null || typeof options !== "object") {
throw new ERR_INVALID_ARG_TYPE("options", "object", options);
}
// Validate envPairs before file (Node.js validation order)
const { envPairs } = options;
if (envPairs !== undefined && !ArrayIsArray(envPairs)) {
throw new ERR_INVALID_ARG_TYPE("options.envPairs", "Array", envPairs);
}
// Validate args
const { args } = options;
if (args !== undefined && !ArrayIsArray(args)) {
throw new ERR_INVALID_ARG_TYPE("options.args", "Array", args);
}
// Validate file
const { file } = options;
if (file == null || typeof file !== "string") {
throw new ERR_INVALID_ARG_TYPE("options.file", "string", file);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Prefer the public spawn(command, args, options) / fork() APIs which construct and validate the options object internally
- If using the internal method, always pass a plain object, defaulting to {}
- Check `options == null || typeof options !== 'object'` and fail early with your own message
Example fix
// before
const cp = new ChildProcess();
cp.spawn(maybeOpts); // maybeOpts can be undefined
// after
const cp = new ChildProcess();
cp.spawn(maybeOpts ?? {}); Defensive patterns
Strategy: type-guard
Validate before calling
if (options == null || typeof options !== 'object' || Array.isArray(options)) {
throw new TypeError('spawn options must be a plain object');
} Type guard
const isSpawnOptions = (o) => o != null && typeof o === 'object' && !Array.isArray(o);
Try / catch
try { child.spawn(options); } catch (err) {
if (err?.code === 'ERR_INVALID_ARG_TYPE' && err.message.includes('"options"')) {
child.spawn({}); // retry with safe defaults
}
} Prevention
- Prefer public spawn()/fork() over the internal ChildProcess#spawn
- Default the whole object: spawn(options ?? {})
- Destructure with defaults at the wrapper boundary so undefined never travels
When it happens
Trigger: Calling child.spawn(null), child.spawn('node'), or a custom spawn wrapper that forwards `undefined` options (e.g. spawn(opts || undefined) where the falsy branch wins).
Common situations: Subclassing ChildProcess or re-implementing normalizeSpawnArguments in app code; optional-chaining bugs where options ?? undefined reaches the internal call; porting code from older Node internals with a different spawn signature.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- ERR_MISSING_ARGS
- No callback function supplied
- ERR_INVALID_ARG_TYPE
- No callback function supplied
- No callback function supplied
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/916d567da24f8c50.
Report an issue: GitHub.