denoland/deno · error · TypeError
Cannot get 'stdout': 'stdout' is not piped
Error message
Cannot get 'stdout': 'stdout' is not piped
What it means
Deno's ChildProcess only creates a .stdout ReadableStream when the Command was spawned with stdout: "piped". The private #stdout field stays null for "inherit", "null", or other stdio settings, and the getter throws a TypeError instead of returning null. Note that spawn() defaults stdout to "inherit", unlike output() which defaults to "piped".
Source
Thrown at ext/process/40_process.js:458
[_stderrRid];
#pid;
get pid() {
return this.#pid;
}
#stdin = null;
get stdin() {
if (this.#stdin == null) {
throw new TypeError("Cannot get 'stdin': 'stdin' is not piped");
}
return this.#stdin;
}
#stdout = null;
get stdout() {
if (this.#stdout == null) {
throw new TypeError("Cannot get 'stdout': 'stdout' is not piped");
}
return this.#stdout;
}
#stderr = null;
get stderr() {
if (this.#stderr == null) {
throw new TypeError("Cannot get 'stderr': 'stderr' is not piped");
}
return this.#stderr;
}
constructor(key = null, {
signal,
rid,
pid,
stdinRid,
stdoutRid,View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Set stdout: "piped" in the Deno.Command options before calling spawn()
- If you only need the finished output, skip spawn() and use await cmd.output() instead, which defaults stdout/stderr to "piped"
- Guard access: only touch child.stdout when the options you passed had stdout: "piped"
Example fix
// before
const child = new Deno.Command("echo", { args: ["hi"] }).spawn();
const body = child.stdout; // TypeError: 'stdout' is not piped
// after
const child = new Deno.Command("echo", { args: ["hi"], stdout: "piped" }).spawn();
const body = child.stdout; Defensive patterns
Strategy: validation
Validate before calling
const opts = { stdout: "piped", ...rest }; // ensure piped before spawn
const wantsStdout = opts.stdout === "piped";
const child = new Deno.Command(cmd, opts).spawn();
if (wantsStdout) { const reader = child.stdout.getReader(); } Type guard
function isStdoutPiped(options: Deno.CommandOptions): boolean {
return options?.stdout === "piped";
} Try / catch
try { stream = child.stdout; } catch (err) { if (err instanceof TypeError && err.message.includes("not piped")) { /* skip capture */ } else throw err; } Prevention
- Always set stdio options explicitly instead of relying on spawn()'s inherit defaults
- Centralize Command construction in one helper so piped-ness is decided in one place
- Remember: spawn() defaults stdio to inherit; output()/outputSync() default to piped
When it happens
Trigger: Accessing child.stdout on a ChildProcess from new Deno.Command(cmd, opts).spawn() when opts.stdout is omitted (defaults to "inherit") or set to "inherit"/"null". For example: const child = new Deno.Command("echo", { args: ["hi"] }).spawn(); child.stdout;
Common situations: Porting code from the removed Deno.run() API; assuming spawn() defaults match output() defaults; helper functions that unconditionally read child.stdout regardless of how the caller configured stdio.
Related errors
- Cannot get 'stderr': 'stderr' is not piped
- Illegal constructor
- Cannot collect output: 'stdout' is locked
- Piped stdin is not supported for this function, use 'Deno.Co
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/185578e3c9499f3d.
Report an issue: GitHub.