sindresorhus/is · error · TypeError

Expected value which is `native Promise`, received value of

Error message

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

What it means

Thrown by `assertNativePromise()` (source/index.ts:1717) when the object type tag isn't exactly 'Promise'. Thenables and third-party promise implementations (Bluebird, Q, jQuery Deferred) fail even though they are awaitable, because this assert demands a native Promise instance specifically.

Source

Thrown at source/index.ts:1719

		throw new TypeError(message ?? typeErrorMessage('Iterable', value));
	}
}

export function assertMap<Key = unknown, Value = unknown>(value: unknown, message?: string): asserts value is Map<Key, Value> {
	if (!isMap(value)) {
		throw new TypeError(message ?? typeErrorMessage('Map', value));
	}
}

export function assertNan(value: unknown, message?: string): asserts value is number {
	if (!isNan(value)) {
		throw new TypeError(message ?? typeErrorMessage('NaN', value));
	}
}

export function assertNativePromise<T = unknown>(value: unknown, message?: string): asserts value is Promise<T> {
	if (!isNativePromise(value)) {
		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));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Normalize to a native promise before asserting: `Promise.resolve(thenable)` always returns a native Promise.
  2. If any awaitable is fine, use the looser `assertPromise()` (accepts thenables) instead of `assertNativePromise()`.
  3. Make sure you pass the result of calling the async function, not the function reference: `assertNativePromise(fn())`.

Example fix

// before
const result = bluebirdApi.fetch();
assertNativePromise(result); // throws — Bluebird promise
// after
const result = Promise.resolve(bluebirdApi.fetch());
assertNativePromise(result);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(value instanceof Promise)) {
  value = Promise.resolve(value); // wraps thenables and plain values into a native Promise
}

Type guard

const isNativePromise = (v: unknown): v is Promise<unknown> => v instanceof Promise;

Prevention

When it happens

Trigger: Calling `assertNativePromise()` with a custom thenable (`{then() {...}}`), a Bluebird/Q promise, a synchronous return value from a function you expected to be async, or an async function itself rather than its invocation result.

Common situations: Libraries or older codebases returning Bluebird promises; mocks/stubs in tests returning plain thenables; forgetting to call the async function (`fn` vs `fn()`); polyfilled environments where Promise is replaced by a non-native implementation.

Related errors


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