sindresorhus/is · error · TypeError

Invalid predicate: ${JSON.stringify(predicate)}

Error message

Invalid predicate: ${JSON.stringify(predicate)}

What it means

Thrown by `validatePredicate` (source/index.ts:410) when an element passed as a predicate to `isAll`/`isAny`/`assertAll`/`assertAny` (or inside a predicate array) is not a function. Every predicate must be a type-guard function `(value: unknown) => boolean`; the error message JSON-stringifies the offending value to aid debugging.

Source

Thrown at source/index.ts:412

	if (predicateArray.length === 0) {
		if (allowEmpty) {
			// Next major release: throw for empty predicate arrays to avoid vacuous results.
			// throw new TypeError('Invalid predicate array');
		} else {
			throw new TypeError('Invalid predicate array');
		}

		return;
	}

	for (const predicate of predicateArray) {
		validatePredicate(predicate);
	}
}

function validatePredicate(predicate: Predicate) {
	if (!isFunction(predicate)) {
		throw new TypeError(`Invalid predicate: ${JSON.stringify(predicate)}`);
	}
}

// Predicate factory overloads - return a type guard when called with only predicates
export function isAll<T1>(predicates: [TypeGuard<T1>]): TypeGuard<T1>;
export function isAll<T1, T2>(predicates: [TypeGuard<T1>, TypeGuard<T2>]): TypeGuard<T1 & T2>;
export function isAll<T1, T2, T3>(predicates: [TypeGuard<T1>, TypeGuard<T2>, TypeGuard<T3>]): TypeGuard<T1 & T2 & T3>;
export function isAll<T1, T2, T3, T4>(predicates: [TypeGuard<T1>, TypeGuard<T2>, TypeGuard<T3>, TypeGuard<T4>]): TypeGuard<T1 & T2 & T3 & T4>;
export function isAll<T1, T2, T3, T4, T5>(predicates: [TypeGuard<T1>, TypeGuard<T2>, TypeGuard<T3>, TypeGuard<T4>, TypeGuard<T5>]): TypeGuard<T1 & T2 & T3 & T4 & T5>;
export function isAll(predicates: ReadonlyArray<TypeGuard<unknown>>): TypeGuard<unknown>;
export function isAll(predicates: readonly Predicate[]): Predicate;
// Evaluator overload - check if all values match the predicate
export function isAll(predicate: Predicate | readonly Predicate[], ...values: unknown[]): boolean;
export function isAll(predicate: Predicate | readonly Predicate[], ...values: unknown[]): boolean | Predicate {
	if (Array.isArray(predicate)) {
		const predicateArray = predicate as readonly Predicate[];
		validatePredicateArray(predicateArray, values.length === 0);

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Pass the function reference, not its result: `isAll(is.string, a, b)` rather than `isAll(is.string(a), b)`.
  2. Check the stringified value in the message — `undefined` usually means a typo'd `is.` property name; verify the method exists in your installed version.
  3. If using a custom predicate, ensure the variable actually holds a function at the call site.

Example fix

// before
assertAll(is.string(name), name, title); // passes boolean, throws

// after
assertAll(is.string, name, title);
Defensive patterns

Strategy: validation

Validate before calling

const validPredicates = new Set(Object.values(is));
predicates.forEach(p => {
  if (typeof p !== 'function' && !validPredicates.has(p)) {
    throw new TypeError(`Not a library predicate: ${String(p)}`);
  }
});

Type guard

function isKnownPredicate(p: unknown): p is (v: unknown) => boolean {
  return typeof p === 'function';
}

Prevention

When it happens

Trigger: Passing a non-function — string, undefined, object, or the *result* of calling a predicate — where a predicate function is expected, e.g. `isAll(is.string(x), y)` instead of `isAll(is.string, x, y)`, or a predicate array containing `undefined` from a typo'd property access like `is.strin`.

Common situations: Accidentally invoking the predicate instead of passing the function reference; typos in `is.xxx` property names yielding `undefined`; passing a string type name ('string') expecting Jest/Joi-style APIs; version upgrades where a method was renamed or removed.

Related errors


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