sindresorhus/is · error · TypeError

Expected value which is `AsyncGeneratorFunction`, received v

Error message

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

What it means

Thrown by `assertAsyncGeneratorFunction(value)` when the value's object tag is not `AsyncGeneratorFunction` — the value was not declared with `async function*`. Both plain async functions and sync generator functions fail, as does an already-invoked generator (the resulting generator object is not the function).

Source

Thrown at source/index.ts:1474

	}
}

// 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));
	}
}

export function assertBigInt64Array(value: unknown, message?: string): asserts value is BigInt64Array {
	if (!isBigInt64Array(value)) {
		throw new TypeError(message ?? typeErrorMessage('BigInt64Array', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Declare the value as `async function*` (both `async` and `*` are required).
  2. Pass the function itself, not the result of calling it.
  3. If the consumer only needs to invoke it and iterate, consider accepting any function and asserting `assert.asyncIterable` on the call result instead.
  4. Set the compile target to ES2018+ to preserve native async generator function tags.

Example fix

// before
register(async function fetchAll() { return items; }); // AsyncFunction, throws
// after
register(async function * fetchAll() { yield * items; });
Defensive patterns

Strategy: type-guard

Validate before calling

if (Object.prototype.toString.call(fn) !== '[object AsyncGeneratorFunction]') { /* handle */ }

Type guard

const isAsyncGeneratorFunction = (fn) =>
  typeof fn === 'function' &&
  Object.prototype.toString.call(fn) === '[object AsyncGeneratorFunction]';

Try / catch

try {
  assert.asyncGeneratorFunction(fn);
} catch (error) {
  if (error instanceof TypeError) { /* async fn, sync generator fn, or plain fn passed */ }
  else { throw error; }
}

Prevention

When it happens

Trigger: Passing `async function` (no star) or `function*` (no async) where `async function*` is required; passing the invoked generator object instead of the function; passing a wrapper (`.bind()`, decorator, jest mock) that returns async iterables but isn't tagged; transpiled output for targets below ES2018 losing the tag.

Common situations: Plugin/handler registries requiring streaming producers where users supply a promise-of-array function instead of an async generator function; TypeScript `target` set below es2018 causing production-only failures; accidentally calling the function at registration time.

Related errors


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