denoland/deno · error · TypeError

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "readableStream" argument must be an instance of ReadableStream

What it means

newStreamReadableFromReadableStream — the engine behind stream.Readable.fromWeb — accepts only a WHATWG ReadableStream (the global web class). A Node streams.Readable, a fetch Response, undefined, or any other object fails the brand check and throws ERR_INVALID_ARG_TYPE.

Source

Thrown at ext/node/polyfills/internal/webstreams/adapters.js:65

}

// Normalize a `writev` completion value to the first real error, or `undefined`
// when every write succeeded. `Promise.all` fulfils with an array (one slot per
// chunk, holes for successes), while a rejection or synchronous throw settles
// with a single scalar error.
function firstWritevError(error) {
  if (Array.isArray(error)) {
    return error.find((e) => e);
  }
  return error == null ? undefined : error;
}

function newStreamReadableFromReadableStream(
  readableStream,
  options = kEmptyObject,
) {
  if (!isReadableStream(readableStream)) {
    throw new ERR_INVALID_ARG_TYPE(
      "readableStream",
      "ReadableStream",
      readableStream,
    );
  }

  validateObject(options, "options");
  const {
    highWaterMark,
    encoding,
    objectMode = false,
    signal,
  } = options;

  if (encoding !== undefined && !Buffer.isEncoding(encoding)) {
    throw new ERR_INVALID_ARG_VALUE(encoding, "options.encoding");
  }
  validateBoolean(objectMode, "options.objectMode");

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass a real web ReadableStream: Readable.fromWeb(response.body)
  2. If the source is a Node stream, convert first with Readable.toWeb(nodeStream) — or just use the Node stream directly
  3. Guard with 'x instanceof ReadableStream' (global web class) before calling

Example fix

// before
const readable = Readable.fromWeb(fs.createReadStream('data.txt')); // throws

// after
const readable = fs.createReadStream('data.txt'); // already a Node Readable
// web->node direction needs a web stream: Readable.fromWeb(response.body)
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(source instanceof ReadableStream)) {
  throw new TypeError('Expected a WHATWG ReadableStream (use Readable.toWeb for Node streams)');
}
const readable = Readable.fromWeb(source);

Type guard

const isWebReadableStream = (s) =>
  typeof ReadableStream !== 'undefined' && s instanceof ReadableStream;

Prevention

When it happens

Trigger: Readable.fromWeb(fs.createReadStream('f')) (a Node stream, not a web stream); Readable.fromWeb(undefined); passing response instead of response.body; grabbing the wrong variable where both node and web variants exist.

Common situations: Bridging fetch/MCP/web APIs into Node stream consumers; direction confusion between toWeb (Node→web) and fromWeb (web→Node); web streams obtained from another realm/implementation.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/ddc4a788b778f1ec. Report an issue: GitHub.