denoland/deno · error · NodeTypeError
ERR_INVALID_SYNC_FORK_INPUT
ERR_INVALID_SYNC_FORK_INPUT
Error message
Asynchronous forks do not support Buffer, TypedArray, DataView or string input: ${value} What it means
While iterating stdio array elements, getValidStdio() recognizes the keywords ('ipc', 'ignore', null, 'pipe', undefined, 'inherit', 'overlapped'), numbers (fds), and objects (fd-holders or Streams). A string element that is not one of those keywords falls into the string branch and throws ERR_INVALID_SYNC_FORK_INPUT, whose message ('Asynchronous forks do not support Buffer, TypedArray, DataView or string input') is inherited verbatim from Node and refers to this class of invalid stdio input values.
Solutions
- Map custom vocabulary to real keywords before spawn: silent->'ignore', null->'ignore', inheritAll->'inherit'
- Whitelist-check every string element: ['pipe','inherit','ignore','overlapped','ipc']
- Trim interpolated values and fall back to 'pipe' for empties
Example fix
// before
const mode = cfg.quiet ? 'silent' : 'pipe';
spawnSync(cmd, args, { stdio: [mode, 'pipe', 'pipe'] });
// after
const mode = cfg.quiet ? 'ignore' : 'pipe';
spawnSync(cmd, args, { stdio: [mode, 'pipe', 'pipe'] }); Defensive patterns
Strategy: type-guard
Validate before calling
const KEYWORDS = new Set(['pipe', 'inherit', 'ignore', 'overlapped', 'ipc']);
const ALIASES = { silent: 'ignore', quiet: 'ignore', null: 'ignore', none: 'ignore', tty: 'inherit' };
function normalizeEntry(e) {
if (typeof e === 'string') {
const t = e.trim();
if (KEYWORDS.has(t)) return t;
if (t in ALIASES) return ALIASES[t];
throw new Error(`invalid stdio entry '${e}'`);
}
return e;
} Type guard
const isValidStdioKeyword = (s) => ['pipe', 'inherit', 'ignore', 'overlapped', 'ipc'].includes(s);
Try / catch
try { spawnSync(cmd, { stdio }); } catch (err) {
if (err?.code === 'ERR_INVALID_SYNC_FORK_INPUT' ||
(err?.code === 'ERR_INVALID_ARG_VALUE' && /stdio/.test(err.message))) {
spawnSync(cmd, { stdio: stdio.map((e) => (typeof e === 'string' && isValidStdioKeyword(e)) ? e : 'pipe') });
}
} Prevention
- Translate library-specific words (silent, null, none) to real keywords before spawning
- Trim interpolated strings; empty strings are never valid stdio entries
- Centralize a normalizeStdio() helper so every spawn site uses the same vocabulary
When it happens
Trigger: stdio: ['silent', 'pipe', 'pipe']; ['null', 'inherit']; ['ipc2', 'pipe']; strings from config or template literals ('${mode}' resolving to an unknown word).
Common situations: Feature-flag strings ('silent', 'null', 'shared') copied from another library's vocabulary; interpolated stdio values that end up empty ('') or with whitespace; docs examples that use 'inherit-all' pseudo-values.
Related errors
- ERR_IPC_SYNC_FORK
- ERR_INVALID_ARG_VALUE
- ERR_IPC_ONE_PIPE
- Cannot get 'stderr': 'stderr' is not piped
- Cannot get 'stdout': 'stdout' is not piped
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/0411fc88eddf44a5.
Report an issue: GitHub.
Appendix: source
Thrown at ext/node/polyfills/internal/child_process.ts:1177
if (sync) {
throw new ERR_IPC_SYNC_FORK();
}
ipc = i;
ipcFd = i;
ArrayPrototypePush(result, { type: "ipc" });
} else if (value === "ignore" || value === null) {
ArrayPrototypePush(result, { type: "ignore" });
} else if (value === "pipe" || value === undefined) {
ArrayPrototypePush(result, { type: "pipe" });
} else if (value === "inherit") {
ArrayPrototypePush(result, { type: "inherit" });
} else if (value === "overlapped") {
ArrayPrototypePush(result, { type: "overlapped" });
} else if (typeof value === "number") {
ArrayPrototypePush(result, { type: "fd", fd: value });
} else if (typeof value === "string") {
// Invalid string value
throw new ERR_INVALID_SYNC_FORK_INPUT(value);
} else if (typeof value === "object" && value !== null) {
// Check if it's a Stream with fd property (like process.stdin/stdout/stderr)
if (
value.fd !== undefined && typeof value.fd === "number"
) {
ArrayPrototypePush(result, { type: "fd", fd: value.fd });
} else if (ObjectPrototypeIsPrototypeOf(Stream.prototype, value)) {
// Valid Stream object but without fd
ArrayPrototypePush(result, { type: "pipe" });
} else {
// Invalid object
throw new ERR_INVALID_ARG_VALUE("stdio", value);
}
} else {
throw new ERR_INVALID_ARG_VALUE("stdio", value);
}
}
View on GitHub (pinned to a961cdec3b)