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
- Validate/parse the bounds before building the range; check `Number.isNaN` on each parsed bound and fail with a clearer domain error.
- Trace where the NaN originates (usually a failed string→number conversion) and fix the source data or parsing.
- 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
- Always pass ranges as a two-element `[min, max]` array with `min <= max`
- Normalize dynamic ranges before use: `const [lo, hi] = a <= b ? [a, b] : [b, a]`
- Guard against NaN/undefined entries when the bounds come from user input or config
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
- Invalid predicate array
- Invalid predicate: ${JSON.stringify(predicate)}
- Invalid number of values
- Expected values which are ${orFormatter.format(uniqueExpecte
- Expected value which is `finite number`, received value of t
AI-assisted analysis of sindresorhus/is@7821031c66 (2026-07-31).
Data as JSON: /data/errors/54bd8739453381fd.json.
Report an issue: GitHub ↗.