sindresorhus/is · error · TypeError

Expected value which is `plain object`, received value of ty

Error message

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

What it means

Thrown by `assert.plainObject()` when the value is not a plain object — one created by `{}`, `new Object()`, or `Object.create(null)`. `isPlainObject` rejects arrays, class instances, Maps, Dates, functions, and primitives, which the looser `assert.object()` would accept. It narrows to `Record<PropertyKey, Value>` for safe key-value access.

Source

Thrown at source/index.ts:1836

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

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

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. If the value is an array of entries or a Map, convert with `Object.fromEntries(value)` before asserting.
  2. If class instances should be accepted, use the looser `assert.object()` instead.
  3. Spread instances into plain objects at the boundary: `{...instance}` — noting this drops methods and prototype.
  4. Check the API contract — a top-level JSON array vs object mismatch means the producer changed shape.

Example fix

// before
const options = new Map([['depth', 2]]);
assert.plainObject(options); // throws: received 'Map'
// after
const options = Object.fromEntries(new Map([['depth', 2]]));
assert.plainObject(options);
Defensive patterns

Strategy: type-guard

Validate before calling

const proto = value === null || typeof value !== 'object' ? undefined : Object.getPrototypeOf(value);
if (typeof value !== 'object' || value === null || (proto !== null && proto !== Object.prototype)) {
  throw new TypeError('Expected a plain object (created by {} or Object.create(null))');
}

Type guard

function isPlainObject(value: unknown): value is Record<string, unknown> {
  if (typeof value !== 'object' || value === null) return false;
  const proto = Object.getPrototypeOf(value);
  return proto === null || proto === Object.prototype;
}

Try / catch

try {
  ow(value, ow.object.plain);
} catch (error) {
  if (error instanceof ArgumentError) {
    throw new TypeError(`Options must be a plain object literal: ${error.message}`);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.plainObject(value)` with an array (a common surprise — arrays are objects but not plain), a class instance, a Map, null, undefined, or a value deserialized into a custom prototype.

Common situations: API returning a JSON array when an object was expected (or vice versa); passing a class-based model/ORM entity where a plain options bag is expected; structuredClone or cross-realm objects with unexpected prototypes; a Map used as a dictionary instead of a plain object.

Related errors


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