sindresorhus/is · error · TypeError

Expected value which is `AsyncGenerator`, received value of

Error message

Expected value which is `AsyncGenerator`, received value of type `${is(value)}`.

What it means

Thrown by `assertAsyncGenerator(value)` when the value is not an async generator object — the object produced by calling an `async function*`. The check requires an async-iterable whose object tag is `AsyncGenerator`; hand-rolled objects implementing `Symbol.asyncIterator`, plain async functions, or the generator function itself (uncalled) all fail.

Source

Thrown at source/index.ts:1468

	}
}

export function assertArrayLike<T = unknown>(value: unknown, message?: string): asserts value is ArrayLike<T> {
	if (!isArrayLike(value)) {
		throw new TypeError(message ?? typeErrorMessage('array-like', value));
	}
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export function assertAsyncFunction(value: unknown, message?: string): asserts value is Function {
	if (!isAsyncFunction(value)) {
		throw new TypeError(message ?? typeErrorMessage('AsyncFunction', value));
	}
}

export function assertAsyncGenerator(value: unknown, message?: string): asserts value is AsyncGenerator {
	if (!isAsyncGenerator(value)) {
		throw new TypeError(message ?? typeErrorMessage('AsyncGenerator', value));
	}
}

export function assertAsyncGeneratorFunction(value: unknown, message?: string): asserts value is AsyncGeneratorFunction {
	if (!isAsyncGeneratorFunction(value)) {
		throw new TypeError(message ?? typeErrorMessage('AsyncGeneratorFunction', value));
	}
}

export function assertAsyncIterable<T = unknown>(value: unknown, message?: string): asserts value is AsyncIterable<T> {
	if (!isAsyncIterable(value)) {
		throw new TypeError(message ?? typeErrorMessage('AsyncIterable', value));
	}
}

export function assertBigint(value: unknown, message?: string): asserts value is bigint {
	if (!isBigint(value)) {
		throw new TypeError(message ?? typeErrorMessage('bigint', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Call the generator function first: pass `gen()` (the generator object), not `gen`.
  2. If any async-iterable should be accepted, use `assert.asyncIterable` instead — it covers streams and custom iterables.
  3. Ensure the source is declared `async function*`, not a plain function returning an object.
  4. Compile to ES2018+ so native async generators keep their tag.

Example fix

// before
async function * pages() { /* ... */ }
consume(pages); // function, not generator object — throws
// after
consume(pages());
Defensive patterns

Strategy: type-guard

Validate before calling

const isAsyncGen = v => v != null && typeof v.next === 'function' && typeof v[Symbol.asyncIterator] === 'function';
if (!isAsyncGen(value)) { /* handle */ }

Type guard

function isAsyncGenerator(value) {
  return value != null && typeof value.next === 'function' &&
    typeof value[Symbol.asyncIterator] === 'function';
}

Try / catch

try {
  assert.asyncGenerator(value);
} catch (error) {
  if (error instanceof TypeError) { /* passed the generator function instead of calling it? */ }
  else { throw error; }
}

Prevention

When it happens

Trigger: Passing the async generator function without invoking it (`gen` instead of `gen()`); passing a sync generator object; passing a custom async iterable (e.g. a Node Readable stream or an object with `[Symbol.asyncIterator]`) that is async-iterable but not a true AsyncGenerator; transpiled code where the AsyncGenerator tag is lost.

Common situations: Forgetting the call parentheses when handing a generator to a consumer; treating Node streams or paginated API iterators as generators; downlevel transpilation (pre-ES2018 targets) replacing native async generators with polyfilled objects lacking the tag.

Related errors


AI-assisted analysis of sindresorhus/is@7821031c66 (2026-07-31). Data as JSON: /data/errors/fe6498b5c2b73b56.json. Report an issue: GitHub ↗.