denoland/deno · error
Invalid stdio count
Error message
Invalid stdio count
What it means
uv_stdio_create() sizes the child's stdio buffer from options.stdio. libuv/CreateProcess support at most 255 streams, so a stdio vector longer than 255 entries is rejected up front with InvalidInput 'Invalid stdio count' (vectors shorter than 3 are padded up to stdin/stdout/stderr).
Source
Thrown at runtime/subprocess_windows/src/process_stdio.rs:253
size_of::<HANDLE>(),
)
}
}
#[derive(Debug, Clone, Copy)]
pub enum StdioContainer {
Ignore,
InheritFd(i32),
RawHandle(HANDLE),
}
#[inline(never)]
pub(crate) fn uv_stdio_create(
options: &SpawnOptions,
) -> Result<StdioBuffer, std::io::Error> {
let mut count = options.stdio.len();
if count > 255 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Invalid stdio count",
));
} else if count < 3 {
count = 3;
}
let mut buffer = StdioBuffer::new(count);
for i in 0..count {
let fdopt = if i < options.stdio.len() {
options.stdio[i]
} else {
StdioContainer::Ignore
};
match fdopt {
StdioContainer::RawHandle(handle) => {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Trim the stdio vector to the streams you actually use (normally 3: stdin, stdout, stderr)
- Fix the loop that generates one stdio entry per item
- Pass extra data through files or pipes set up after spawn instead of extra stdio slots
Example fix
// before
const stdio = openFiles.map(() => "pipe"); // 300 entries
spawn(prog, { stdio: ["pipe", "pipe", "pipe", ...stdio] });
// after
spawn(prog, { stdio: ["pipe", "pipe", "pipe"] }); Defensive patterns
Strategy: validation
Validate before calling
if (stdio.length > 255) {
throw new Error(`stdio count ${stdio.length} exceeds the Windows limit of 255`);
} Type guard
const isWithinStdioLimit = (stdio: unknown[]): stdio is unknown[] => stdio.length <= 255;
Prevention
- Keep stdio to the three standard streams unless a specific fd is required
- Assert on stdio length when it is generated programmatically
- Move bulk data transfer to files or post-spawn pipes
When it happens
Trigger: Spawning with a stdio array longer than 255 entries - reachable from Node-compat child_process.spawn({ stdio: [...many] }) or from programmatic code that generates one stdio entry per open file.
Common situations: A loop bug that appends one "pipe" per iteration; porting code that wires dozens or hundreds of fds into a child; copy-paste expansion of stdio configuration arrays.
Related errors
- Invalid handle
- GetHandleInformation failed (error {})
- Could not open NUL device (error {})
- SetStdHandle failed (error {})
- {}: ({}) {}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/b73ed2d4eccb0e91.
Report an issue: GitHub.