sindresorhus/is · error · TypeError

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

Error message

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

What it means

Thrown by `isInRange` (source/index.ts:679) when a two-element range array contains `NaN` in either position. Since comparisons against `NaN` are always false, a NaN bound would make the range check silently meaningless, so the library fails fast instead.

Source

Thrown at source/index.ts:686

		&& (value as HTMLElement).nodeType === NODE_TYPE_ELEMENT
		&& isString((value as HTMLElement).nodeName)
		&& !isPlainObject(value)
		&& DOM_PROPERTIES_TO_CHECK.every(property => property in value);
}

export function isInfinite<Input>(value: Input): value is NumericGuardResult<Input, PositiveInfinity | NegativeInfinity>;
export function isInfinite(value: unknown): boolean {
	return value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY;
}

export function isInRange(value: number, range: number | [number, number]): value is number {
	if (isNumber(range)) {
		return value >= Math.min(0, range) && value <= Math.max(range, 0);
	}

	if (isArray(range) && range.length === 2) {
		if (Number.isNaN(range[0]) || Number.isNaN(range[1])) {
			throw new TypeError(`Invalid range: ${JSON.stringify(range)}`);
		}

		return value >= Math.min(...range) && value <= Math.max(...range);
	}

	throw new TypeError(`Invalid range: ${JSON.stringify(range)}`);
}

export function isInt16Array(value: unknown): value is Int16Array {
	return getObjectType(value) === 'Int16Array';
}

export function isInt32Array(value: unknown): value is Int32Array {
	return getObjectType(value) === 'Int32Array';
}

export function isInt8Array(value: unknown): value is Int8Array {
	return getObjectType(value) === 'Int8Array';

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Validate/parse the bounds before building the range; check `Number.isNaN` on each parsed bound and fail with a clearer domain error.
  2. Trace where the NaN originates (usually a failed string→number conversion) and fix the source data or parsing.
  3. Provide explicit defaults for optional bounds instead of letting them fall through as NaN.

Example fix

// before
const max = Number(process.env.MAX); // env unset -> NaN
isInRange(n, [0, max]); // throws

// after
const max = Number(process.env.MAX ?? '100');
if (Number.isNaN(max)) throw new Error('MAX must be numeric');
isInRange(n, [0, max]);
Defensive patterns

Strategy: validation

Validate before calling

function isValidRange(range) {
  return Array.isArray(range) && range.length === 2 &&
    range.every(n => typeof n === 'number' && !Number.isNaN(n)) &&
    range[0] <= range[1];
}
if (!isValidRange(range)) throw new TypeError('Range must be [min, max] with min <= max');

Type guard

function isRange(v: unknown): v is [number, number] {
  return Array.isArray(v) && v.length === 2 && v.every(n => typeof n === 'number') && v[0] <= v[1];
}

Prevention

When it happens

Trigger: Calling `isInRange(value, [min, max])` where `min` or `max` is `NaN` — e.g. `isInRange(5, [Number.parseInt('abc', 10), 10])` or a bound computed from `0/0` or a failed numeric conversion.

Common situations: Range bounds parsed from strings (env vars, query params, config) with `parseInt`/`Number` that fail and yield NaN; arithmetic on undefined fields (`undefined * 2`); spreadsheet/CSV imports with blank cells.

Related errors


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