sindresorhus/is · error · TypeError

Expected value which is `positive integer`, received value…

Error message

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

What it means

Thrown by `assert.positiveInteger()` when the value is not an integer strictly greater than zero. Both conditions are checked at runtime: non-numbers, floats, zero, negative integers, NaN, and Infinity all fail. Used to guard counts, sizes, IDs, and limits that must be whole and positive.

Solutions

  1. If zero is legitimately valid in your domain, use `assert.integer()` plus a `>= 0` check (or the library's non-negative variant) instead.
  2. Convert string inputs with `Number.parseInt(raw, 10)` before asserting, and handle NaN from failed parses.
  3. Apply a floor/default before asserting: `const limit = Math.max(1, Math.trunc(requested))`.
  4. Trace where 0 or a negative slipped in — often an empty collection or an uninitialized counter.

Example fix

// before
const limit = Number(req.query.limit); // '0' or undefined → 0 or NaN
assert.positiveInteger(limit);
// after
const limit = Math.max(1, Number.parseInt(req.query.limit ?? '10', 10) || 10);
assert.positiveInteger(limit);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

function isPositiveInteger(value: unknown): value is number {
  return typeof value === 'number' && Number.isInteger(value) && value > 0;
}

Try / catch

try {
  ow(value, ow.number.positive.integer);
} catch (error) {
  if (error instanceof ArgumentError) {
    throw new RangeError(`Count/size must be a positive integer: ${error.message}`);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.positiveInteger(value)` with 0 (zero is not positive), -1, 2.5, NaN, Infinity, a numeric string like '5', or undefined for an unset parameter.

Common situations: Pagination/limit parameters arriving as strings from query strings; a default of 0 used where a minimum of 1 is required; array-length math producing 0 for empty inputs; NaN from parsing a missing env var like `Number(process.env.WORKERS)`.

Related errors


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

Appendix: source

Thrown at source/index.ts:1842

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

export function assertOddInteger(value: number, message?: string): asserts value is number {
	if (!isOddInteger(value)) {
		throw new TypeError(message ?? typeErrorMessage('odd integer', value));
	}
}

export function assertPlainObject<Value = unknown>(value: unknown, message?: string): asserts value is Record<PropertyKey, Value> {
	if (!isPlainObject(value)) {
		throw new TypeError(message ?? typeErrorMessage('plain object', value));
	}
}

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

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

export function assertPrimitive(value: unknown, message?: string): asserts value is Primitive {
	if (!isPrimitive(value)) {
		throw new TypeError(message ?? typeErrorMessage('primitive', value));
	}
}

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

View on GitHub (pinned to 7821031c66)