sindresorhus/is · error · TypeError

Expected value which is `primitive`, received value of type

Error message

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

What it means

Thrown by `assert.primitive()` when the value is not a JavaScript primitive — string, number, bigint, boolean, symbol, null, or undefined. Any object, array, function, or class instance fails. Used where a value must be safely comparable by identity, serializable as a scalar, or usable as a simple key/value.

Source

Thrown at source/index.ts:1854

		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));
	}
}

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));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Extract the scalar you actually need before asserting, e.g. pass `entity.id` rather than `entity`.
  2. Unbox wrapper objects with `.valueOf()` or by avoiding `new String()`/`new Number()` construction.
  3. If objects should be stringified for this use, do it explicitly (`JSON.stringify`) rather than relying on implicit coercion.
  4. Check the received type in the message — 'Object'/'Array' points directly at which composite leaked in.

Example fix

// before
assert.primitive(user); // throws: received 'Object'
cache.set(user, data);
// after
assert.primitive(user.id);
cache.set(user.id, data);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
  throw new TypeError(`Expected primitive, got ${typeof value}`);
}

Type guard

function isPrimitive(value: unknown): value is string | number | boolean | bigint | symbol | null | undefined {
  return value === null || (typeof value !== 'object' && typeof value !== 'function');
}

Try / catch

try {
  ow(value, ow.any(ow.string, ow.number, ow.boolean, ow.null_, ow.undefined));
} catch (error) {
  if (error instanceof ArgumentError) {
    throw new TypeError(`Expected a primitive value: ${error.message}`);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.primitive(value)` with an object, array, function, Date, or boxed primitive (`new String('x')`, `new Number(1)` — boxed wrappers are objects, not primitives).

Common situations: Passing a whole object where a scalar ID was expected (e.g. `user` instead of `user.id`); values from libraries that return boxed/wrapped types; template or logging helpers receiving structured data instead of a displayable scalar; cache keys built from objects.

Related errors


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