sindresorhus/is · error · TypeError

Expected value which is `odd integer`, received value of typ

Error message

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

What it means

Thrown by `assert.oddInteger()` when the number is not an odd integer. Note the parameter is already typed `number` — this assert validates the runtime value's mathematical property (integer and odd), not just its type. Even integers, non-integer floats, NaN, and Infinity all fail.

Source

Thrown at source/index.ts:1830

	}
}

// eslint-disable-next-line @typescript-eslint/no-restricted-types
export function assertObject(value: unknown, message?: string): asserts value is object {
	if (!isObject(value)) {
		throw new TypeError(message ?? typeErrorMessage('Object', value));
	}
}

export function assertObservable(value: unknown, message?: string): asserts value is ObservableLike {
	if (!isObservable(value)) {
		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));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Coerce to a valid odd integer before asserting, e.g. `const odd = 2 * Math.floor(n / 2) + 1`.
  2. Check for NaN upstream — a failed parse silently produces NaN which fails here with a confusing 'number' received-type.
  3. If odd is not a real requirement, use `assert.integer()` instead.
  4. Validate user-facing inputs with a clear domain error ('window size must be odd') before this internal assert.

Example fix

// before
const kernel = imageWidth / 10; // may be even or fractional
assert.oddInteger(kernel);
// after
const kernel = 2 * Math.floor(imageWidth / 20) + 1;
assert.oddInteger(kernel);
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(value) || Math.abs(value % 2) !== 1) {
  throw new TypeError(`Expected odd integer, got ${value}`);
}

Type guard

function isOddInteger(value: unknown): value is number {
  return typeof value === 'number' && Number.isInteger(value) && Math.abs(value % 2) === 1;
}

Try / catch

try {
  ow(value, ow.number.oddInteger);
} catch (error) {
  if (error instanceof ArgumentError) {
    throw new RangeError(`Value must be an odd integer: ${error.message}`);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.oddInteger(value)` with an even integer (4), a float (3.5), NaN, Infinity, or the result of a division that didn't produce a whole number. Typical for parameters that must be odd, like kernel/window sizes or center-symmetric dimensions.

Common situations: Computing a window or kernel size from user input or image dimensions and getting an even result; off-by-one in loop math producing evens; parsing '3' correctly but then doubling it; NaN from a failed Number() conversion propagating in.

Related errors


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