sindresorhus/is · error · TypeError

Expected value which is `tuple-like`, received value of type

Error message

Expected value which is `tuple-like`, received value of type `${is(value)}`.

What it means

Thrown by `assert.tupleLike()` (assertTupleLike at source/index.ts:1912) when `isTupleLike(value, guards)` fails. Unlike the other assertions it takes a second argument: an array of type guards, one per tuple position. The value must be an array whose length equals `guards.length` AND where every element passes its corresponding guard — a length mismatch or one wrong-typed element fails the whole assertion.

Source

Thrown at source/index.ts:1914

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

export function assertSymbol(value: unknown, message?: string): asserts value is symbol {
	if (!isSymbol(value)) {
		throw new TypeError(message ?? typeErrorMessage('symbol', value));
	}
}

export function assertTruthy<T>(value: T | Falsy, message?: string): asserts value is T {
	if (!isTruthy(value)) {
		throw new TypeError(message ?? typeErrorMessage('truthy', value));
	}
}

export function assertTupleLike<T extends Array<TypeGuard<unknown>>>(value: unknown, guards: [...T], message?: string): asserts value is ResolveTypesOfTypeGuardsTuple<T> {
	if (!isTupleLike(value, guards)) {
		throw new TypeError(message ?? typeErrorMessage('tuple-like', value));
	}
}

export function assertTypedArray(value: unknown, message?: string): asserts value is TypedArray {
	if (!isTypedArray(value)) {
		throw new TypeError(message ?? typeErrorMessage('TypedArray', value));
	}
}

export function assertUint16Array(value: unknown, message?: string): asserts value is Uint16Array {
	if (!isUint16Array(value)) {
		throw new TypeError(message ?? typeErrorMessage('Uint16Array', value));
	}
}

export function assertUint32Array(value: unknown, message?: string): asserts value is Uint32Array {
	if (!isUint32Array(value)) {
		throw new TypeError(message ?? typeErrorMessage('Uint32Array', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Check the tuple length: the guards array length must exactly match the value's length — update the guards when the tuple shape changes.
  2. Verify each element's type against its positional guard; coerce upstream (e.g. `Number(parts[0])`) where parsing produced strings.
  3. If trailing elements are optional, validate with a custom check or `is.array` plus per-element guards instead of tupleLike.

Example fix

// before
const pair = line.split(','); // ['12.5', 'label'] — strings
assert.tupleLike(pair, [is.number, is.string]);
// after
const parts = line.split(',');
const pair = [Number(parts[0]), parts[1]];
assert.tupleLike(pair, [is.number, is.string]);
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(value) || value.length !== expectedLength) {
  throw new TypeError(`Expected a tuple of length ${expectedLength}`);
}

Type guard

function isTupleOfLength<N extends number>(value: unknown, length: N): value is unknown[] & {length: N} {
  return Array.isArray(value) && value.length === length;
}

Try / catch

try {
  assert.tupleLike(value, guards);
} catch (error) {
  if (error instanceof TypeError) {
    // wrong length or an element failed its per-position guard
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.tupleLike(value, [is.number, is.string])` with a non-array, an array of the wrong length (e.g. 3 elements against 2 guards), or an array where some position fails its guard (e.g. `['1', 'a']` where index 0 must be a number).

Common situations: Destructuring API responses expected as fixed pairs (`[lat, lng]`, `[key, value]`) where the server added/removed fields; CSV or split-string rows with missing columns; numeric positions arriving as strings after JSON/query-string parsing; passing the guards array with the wrong arity after refactoring the tuple shape.

Related errors


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