denoland/deno · error · ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
ERR_INVALID_ARG_TYPE("stream", "Writable", stream) What it means
The Readline helper class in node:readline/promises (used for cursor control on a single output stream) requires its constructor argument to be a Writable stream. The polyfill checks isWritable(stream) from internal/streams/utils and throws ERR_INVALID_ARG_TYPE('stream', 'Writable', stream) for anything else — strings, numbers, readables like process.stdin or fs.createReadStream().
Source
Thrown at ext/node/polyfills/internal/readline/promises.mjs:42
const { ERR_INVALID_ARG_TYPE } = core.loadExtScript(
"ext:deno_node/internal/errors.ts",
);
const {
kClearToLineBeginning,
kClearToLineEnd,
kClearLine,
kClearScreenDown,
} = CSI;
class Readline {
#autoCommit = false;
#stream;
#todo = [];
constructor(stream, options = undefined) {
if (!isWritable(stream)) {
throw new ERR_INVALID_ARG_TYPE("stream", "Writable", stream);
}
this.#stream = stream;
if (options?.autoCommit != null) {
validateBoolean(options.autoCommit, "options.autoCommit");
this.#autoCommit = options.autoCommit;
}
}
/**
* Moves the cursor to the x and y coordinate on the given stream.
* @param {integer} x
* @param {integer} [y]
* @returns {Readline} this
*/
cursorTo(x, y = undefined) {
validateInteger(x, "x");
if (y != null) validateInteger(y, "y");
View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass a Writable: process.stdout, process.stderr, or fs.createWriteStream(path)
- If you meant a full prompt interface, use createInterface({ input, output }) instead of new Readline(stream)
- Check the argument: typeof stream?.write === 'function' before constructing
Example fix
// before
const rl = new Readline('log.txt');
// after
const rl = new Readline(fs.createWriteStream('log.txt')); Defensive patterns
Strategy: type-guard
Validate before calling
import { Readline } from 'node:readline/promises';
function makeReadline(stream: unknown) {
if (stream && typeof (stream as NodeJS.WritableStream).write === 'function') {
return new Readline(stream as NodeJS.WritableStream);
}
throw new TypeError('stream must be a Writable (e.g. process.stdout)');
} Type guard
const isNodeWritable = (s: unknown): s is NodeJS.WritableStream => !!s && typeof (s as NodeJS.WritableStream)?.write === 'function';
Try / catch
try {
rl = new Readline(stream);
} catch (err) {
if (err?.code === 'ERR_INVALID_ARG_TYPE' && /Writable/.test(err.message)) {
rl = new Readline(process.stdout);
} else throw err;
} Prevention
- Pass the output side (process.stdout / a write stream), never an input or a path string
- For full prompting use createInterface({ input, output }), not new Readline()
When it happens
Trigger: new Readline(process.stdin); new Readline('out.txt'); new Readline(fs.createReadStream(p)); passing the interface itself or null where a Writable is expected; forgetting the argument so stream is undefined.
Common situations: Confusing input/output when wiring terminal helpers (stream must be the output side, e.g. process.stdout); passing a file path string instead of a write stream; using the Readline class where createInterface({ input, output }) was intended.
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_STREAM_NULL_VALUES
- ERR_METHOD_NOT_IMPLEMENTED
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_CURSOR_POS
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/ac23add43ff4e437.
Report an issue: GitHub.