sindresorhus/is · error · TypeError

Invalid predicate array

Error message

Invalid predicate array

What it means

Thrown by `validatePredicateArray` (source/index.ts:393) when a predicate array passed to a combinator like `isAll`/`isAny` (or their assert counterparts) is empty and empty arrays are not allowed in that call path. An empty predicate array would produce vacuous results (everything or nothing matches), so the library rejects it; a comment notes the next major release will throw for the currently-allowed empty cases too.

Source

Thrown at source/index.ts:399

		weakRef: isWeakRef,
		weakSet: isWeakSet,
		whitespaceString: isWhitespaceString,
	},
);

function isAbsoluteModule2(remainder: 0 | 1) {
	return (value: unknown): value is number => isInteger(value) && Math.abs(value % 2) === remainder;
}

type TypeGuard<T> = (value: unknown) => value is T;

function validatePredicateArray(predicateArray: readonly Predicate[], allowEmpty: boolean) {
	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>;

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Ensure the predicate array contains at least one type-guard function before calling the combinator.
  2. If the list is built dynamically, guard the call: skip validation or treat it as pass/fail explicitly when the list is empty.
  3. Check for variable mix-ups — confirm you're passing the intended, populated array.

Example fix

// before
const predicates = [];
isAny(predicates, value); // throws TypeError

// after
const predicates = [is.string, is.number];
isAny(predicates, value);
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(predicates) || predicates.length === 0) {
  throw new TypeError('Expected a non-empty array of predicates');
}

Type guard

function isPredicateArray(v: unknown): v is Function[] {
  return Array.isArray(v) && v.length > 0 && v.every(p => typeof p === 'function' || typeof p === 'object');
}

Prevention

When it happens

Trigger: Calling `isAny([])`, `assertAny([], ...)`, or another predicate-array API with a zero-length array in a code path where `allowEmpty` is false. Typically the array is built dynamically (filter/map) and ends up empty.

Common situations: Dynamically building a predicate list from configuration or feature flags and all entries get filtered out; refactoring that removes the last predicate from a shared list; passing the wrong variable (an empty array) by mistake.

Related errors


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