denoland/deno · error · TypeError
ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
Error message
The argument 'stdio' is invalid. Received ${inspected} What it means
In Deno's node:child_process polyfill, stdioStringToArray() expands a shorthand string stdio option into the 3-element array [stdio, stdio, stdio]. Only 'ignore', 'overlapped', 'pipe' and 'inherit' are accepted; any other string falls to the default branch and throws ERR_INVALID_ARG_VALUE. This runs on the fork()/spawn option-normalization path.
Source
Thrown at ext/node/polyfills/internal/child_process.ts:209
}
function stdioStringToArray(
stdio,
channel,
) {
const options = [];
switch (stdio) {
case "ignore":
case "overlapped":
case "pipe":
ArrayPrototypePush(options, stdio, stdio, stdio);
break;
case "inherit":
ArrayPrototypePush(options, stdio, stdio, stdio);
break;
default:
throw new ERR_INVALID_ARG_VALUE("stdio", stdio);
}
if (channel) ArrayPrototypePush(options, channel);
return options;
}
const kClosesNeeded = Symbol("_closesNeeded");
const kClosesReceived = Symbol("_closesReceived");
const kCanDisconnect = Symbol("_canDisconnect");
const kChildStdioUsedAsInput = Symbol("childStdioUsedAsInput");
const childStdioStreamsByFd = new SafeMap();
let emittedShellDeprecation = false;
// We only want to emit a close event for the child process when all of
// the writable streams have closed. The value of `child[kClosesNeeded]` should be 1 +
// the number of opened writable streams (note this excludes `stdin`).
function maybeClose(child) {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use one of the four valid strings: 'pipe', 'inherit', 'ignore', 'overlapped'
- For IPC use the array form, e.g. stdio: ['ipc', 'pipe', 'pipe'], or just call fork() which wires IPC for you
- For per-fd control pass a full array: stdio: ['inherit', 'pipe', 'ignore']
- Trim/validate the string before passing if it comes from user input or config
Example fix
// before
fork(script, { stdio: 'silent' });
// after
fork(script, { silent: true });
// or
fork(script, { stdio: ['ignore', 'pipe', 'pipe'] }); Defensive patterns
Strategy: validation
Validate before calling
const VALID = new Set(['pipe', 'inherit', 'ignore', 'overlapped']);
function toStdioArray(shorthand) {
if (typeof shorthand === 'string' && !VALID.has(shorthand)) {
throw new Error(`invalid stdio shorthand '${shorthand}'; expected one of ${[...VALID].join(', ')}`);
}
return typeof shorthand === 'string' ? [shorthand, shorthand, shorthand] : shorthand;
} Type guard
const isStdioShorthand = (s) => typeof s === 'string' && ['pipe', 'inherit', 'ignore', 'overlapped'].includes(s);
Try / catch
try { fork(script, { stdio: mode }); } catch (err) {
if (err?.code === 'ERR_INVALID_ARG_VALUE' && /stdio/.test(err.message)) {
// fall back to explicit array form
fork(script, { stdio: ['pipe', 'pipe', 'pipe'] });
}
} Prevention
- Remember the four valid shorthands: pipe, inherit, ignore, overlapped
- 'ipc' is never valid as a string shorthand — use an array element or fork()
- Trim and lowercase-check config-sourced strings against the whitelist
When it happens
Trigger: fork(modulePath, { stdio: 'ipc' }), stdio: 'silent', stdio: 'null', stdio: 'inherit ' (trailing space), or any typo'd keyword — i.e. any string shorthand outside the four valid values.
Common situations: Confusing spawn's legacy `silent: true` boolean with a stdio string; writing stdio: 'null' instead of 'ignore'; trying to request an IPC channel with the string 'ipc' (only valid as an array element); values built by string concatenation that pick up whitespace.
Related errors
- ERR_IPC_ONE_PIPE
- ERR_IPC_SYNC_FORK
- ERR_INVALID_SYNC_FORK_INPUT
- ERR_CHILD_PROCESS_IPC_REQUIRED
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/b9ec7a5ed5473e22.
Report an issue: GitHub.