sindresorhus/is · error · TypeError
Expected value which is `Node.js Stream`, received value of
Error message
Expected value which is `Node.js Stream`, received value of type `${is(value)}`. What it means
Thrown by `assertNodeStream()` (source/index.ts:1735) when `isNodeStream()` fails; that predicate duck-types the value as `isObject(value) && isFunction(value.pipe) && !isObservable(value)`. So it needs an object with a callable `pipe` method that is not an Observable — it does not require inheriting from Node's stream classes.
Source
Thrown at source/index.ts:1737
throw new TypeError(message ?? typeErrorMessage('native Promise', value));
}
}
export function assertNegativeInteger(value: unknown, message?: string): asserts value is number {
if (!isNegativeInteger(value)) {
throw new TypeError(message ?? typeErrorMessage('negative integer', value));
}
}
export function assertNegativeNumber(value: unknown, message?: string): asserts value is number {
if (!isNegativeNumber(value)) {
throw new TypeError(message ?? typeErrorMessage('negative number', value));
}
}
export function assertNodeStream(value: unknown, message?: string): asserts value is NodeStream {
if (!isNodeStream(value)) {
throw new TypeError(message ?? typeErrorMessage('Node.js Stream', value));
}
}
export function assertNonEmptyArray<T = unknown, Item = unknown>(value: T | Item[], message?: string): asserts value is [Item, ...Item[]] {
if (!isNonEmptyArray(value)) {
throw new TypeError(message ?? typeErrorMessage('non-empty array', value));
}
}
export function assertNonEmptyMap<Key = unknown, Value = unknown>(value: unknown, message?: string): asserts value is Map<Key, Value> {
if (!isNonEmptyMap(value)) {
throw new TypeError(message ?? typeErrorMessage('non-empty map', value));
}
}
export function assertNonEmptyObject<Key extends keyof any = string, Value = unknown>(value: unknown, message?: string): asserts value is Record<Key, Value> {
if (!isNonEmptyObject(value)) {
throw new TypeError(message ?? typeErrorMessage('non-empty object', value));View on GitHub ↗ (pinned to 7821031c66)
Solutions
- Convert web streams: `stream.Readable.fromWeb(webStream)` (Node 17+) before asserting.
- Create a stream from in-memory data: `stream.Readable.from(bufferOrIterable)`.
- For RxJS Observables, this assert rejects them by design — convert or use an Observable-aware path instead.
- Verify the producer actually returned a stream (not undefined from an error path) before the assert site.
Example fix
// before
const body = (await fetch(url)).body;
assertNodeStream(body); // throws — WHATWG ReadableStream
// after
import {Readable} from 'node:stream';
const body = Readable.fromWeb((await fetch(url)).body);
assertNodeStream(body); Defensive patterns
Strategy: type-guard
Validate before calling
const {Stream} = require('node:stream');
if (!(value instanceof Stream) && !(value && typeof value.pipe === 'function')) {
throw new TypeError('Expected a Node.js Stream');
} Type guard
const isNodeStream = (v: unknown): v is NodeJS.ReadableStream | NodeJS.WritableStream => v !== null && typeof v === 'object' && typeof (v as any).pipe === 'function';
Prevention
- Web streams (ReadableStream from fetch) are NOT Node streams — bridge with stream.Readable.fromWeb / stream.Readable.toWeb
- In browser bundles Node streams don't exist; gate stream-based code paths by runtime environment
- Prefer node:stream utilities (isReadable, isWritable in modern Node) for finer-grained checks than duck-typed .pipe
When it happens
Trigger: Calling `assertNodeStream()` with a WHATWG web stream (ReadableStream — has `pipeTo`/`pipeThrough`, not `pipe`), a Buffer or string of the full content, an RxJS Observable (explicitly excluded even if it has pipe), an async iterator, or a closed/undefined stream variable.
Common situations: The fetch-API migration is the big one: `fetch()` response bodies and many modern APIs (undici, Node 18+ `fs.openAsBlob`, web streams) return WHATWG streams, not Node streams. Also passing RxJS Observables (whose `.pipe` exists but is deliberately rejected), or file contents read eagerly instead of streamed.
Related errors
- Expected value which is `Blob`, received value of type `${is
- Expected value which is `Buffer`, received value of type `${
- Expected value which is `FormData`, received value of type `
- Expected value which is `Int8Array`, received value of type
- Expected value which is `Array`, received value of type `${i
AI-assisted analysis of sindresorhus/is@7821031c66 (2026-07-31).
Data as JSON: /data/errors/bd1c2d8a7373d3b7.json.
Report an issue: GitHub ↗.