sindresorhus/is · error · TypeError

Expected value which is `safe integer`, received value of ty

Error message

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

What it means

Thrown by `assert.safeInteger()` (assertSafeInteger at source/index.ts:1876) when `isSafeInteger` (backed by `Number.isSafeInteger`) rejects the value. A safe integer is an integer in the range ±2^53−1 that can be exactly represented in an IEEE-754 double. Non-numbers, floats, NaN, Infinity, BigInt, and integers beyond ±9007199254740991 all fail.

Source

Thrown at source/index.ts:1878

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

export function assertPropertyKey(value: unknown, message?: string): asserts value is PropertyKey {
	if (!isPropertyKey(value)) {
		throw new TypeError(message ?? typeErrorMessage('PropertyKey', value));
	}
}

export function assertRegExp(value: unknown, message?: string): asserts value is RegExp {
	if (!isRegExp(value)) {
		throw new TypeError(message ?? typeErrorMessage('RegExp', value));
	}
}

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

export function assertSet<T = unknown>(value: unknown, message?: string): asserts value is Set<T> {
	if (!isSet(value)) {
		throw new TypeError(message ?? typeErrorMessage('Set', value));
	}
}

export function assertSharedArrayBuffer(value: unknown, message?: string): asserts value is SharedArrayBuffer {
	if (!isSharedArrayBuffer(value)) {
		throw new TypeError(message ?? typeErrorMessage('SharedArrayBuffer', value));
	}
}

export function assertString(value: unknown, message?: string): asserts value is string {
	if (!isString(value)) {
		throw new TypeError(message ?? typeErrorMessage('string', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. If the value is a numeric string, parse it first: `Number.parseInt(value, 10)` and verify no NaN.
  2. For 64-bit IDs beyond MAX_SAFE_INTEGER, keep them as strings or BigInt instead of asserting safe integer.
  3. If floats are acceptable, use `assert.number()` instead; if any integer including unsafe ones, restructure to avoid precision loss.

Example fix

// before
const id = Number(response.userId); // '9223372036854775807'
assert.safeInteger(id);
// after
const id = response.userId; // keep 64-bit IDs as strings
assert.string(id);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
  throw new TypeError(`Expected a safe integer, got ${value}`);
}

Type guard

function isSafeInteger(value: unknown): value is number {
  return Number.isSafeInteger(value);
}

Try / catch

try {
  assert.safeInteger(value);
} catch (error) {
  if (error instanceof TypeError) {
    // NaN, float, ±Infinity, or |value| > Number.MAX_SAFE_INTEGER
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.safeInteger(value)` with a float (e.g. `1.5`), a numeric string (`'42'`), `NaN` from a failed `parseInt`, a BigInt, or an integer larger than `Number.MAX_SAFE_INTEGER` (common with 64-bit IDs from databases or APIs).

Common situations: Snowflake/64-bit IDs (Twitter, Discord, database bigint columns) parsed as numbers exceeding the safe range; form input or query params arriving as strings; arithmetic producing floats where integers were expected.

Related errors


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