sindresorhus/is · error · TypeError

Expected value which is `negative integer`, received value o

Error message

Expected value which is `negative integer`, received value of type `${is(value)}`.

What it means

Thrown by `assertNegativeInteger()` (source/index.ts:1723) when the value fails `isInteger(value) && value < 0`. Both conditions must hold: a number primitive, whole, and strictly less than zero. Zero, positive integers, negative floats, and numeric strings all fail.

Source

Thrown at source/index.ts:1725

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

export function assertNan(value: unknown, message?: string): asserts value is number {
	if (!isNan(value)) {
		throw new TypeError(message ?? typeErrorMessage('NaN', value));
	}
}

export function assertNativePromise<T = unknown>(value: unknown, message?: string): asserts value is Promise<T> {
	if (!isNativePromise(value)) {
		throw new TypeError(message ?? typeErrorMessage('native Promise', value));
	}
}

export function assertNegativeInteger(value: unknown, message?: string): asserts value is number {
	if (!isNegativeInteger(value)) {
		throw new TypeError(message ?? typeErrorMessage('negative integer', value));
	}
}

export function assertNegativeNumber(value: unknown, message?: string): asserts value is number {
	if (!isNegativeNumber(value)) {
		throw new TypeError(message ?? typeErrorMessage('negative number', value));
	}
}

export function assertNodeStream(value: unknown, message?: string): asserts value is NodeStream {
	if (!isNodeStream(value)) {
		throw new TypeError(message ?? typeErrorMessage('Node.js Stream', value));
	}
}

export function assertNonEmptyArray<T = unknown, Item = unknown>(value: T | Item[], message?: string): asserts value is [Item, ...Item[]] {
	if (!isNonEmptyArray(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty array', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Parse strings first: `Number.parseInt(raw, 10)` before asserting.
  2. If zero is valid in your domain, use `assertNonPositiveNumber()`/adjust the check rather than negative-integer.
  3. Truncate intentional fractional values with `Math.trunc()` if whole negatives are the real requirement.
  4. Trace upstream arithmetic if NaN/-Infinity reaches the assert.

Example fix

// before
const offset = Number(raw) / 3; // may be -1.6667
assertNegativeInteger(offset); // throws
// after
const offset = Math.trunc(Number(raw) / 3);
assertNegativeInteger(offset);
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(value) || value >= 0) {
  throw new RangeError(`Expected negative integer, got ${value}`);
}

Type guard

const isNegativeInteger = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v < 0;

Prevention

When it happens

Trigger: Calling `assertNegativeInteger()` with 0 (not negative), a positive integer, -3.5 (not an integer), '-5' (string), NaN, or -Infinity (not an integer).

Common situations: Off-by-one boundary confusion where 0 was expected to pass; string inputs from CLI/env/query params; results of subtraction that yield floats due to floating-point arithmetic; using -0 works (Number.isInteger(-0) && -0 < 0 is false — -0 fails, another boundary trap).

Related errors


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