sindresorhus/is · error · TypeError

Expected value which is `non-empty object`, received value o

Error message

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

What it means

Thrown by `assertNonEmptyObject()` (source/index.ts:1753) when the value fails `isNonEmptyObject()` — it must be a plain-ish object with at least one own enumerable key. Arrays, Maps, Sets, `null`, and `{}` all fail. On success TypeScript narrows the value to `Record<Key, Value>`.

Source

Thrown at source/index.ts:1755

		throw new TypeError(message ?? typeErrorMessage('Node.js Stream', value));
	}
}

export function assertNonEmptyArray<T = unknown, Item = unknown>(value: T | Item[], message?: string): asserts value is [Item, ...Item[]] {
	if (!isNonEmptyArray(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty array', value));
	}
}

export function assertNonEmptyMap<Key = unknown, Value = unknown>(value: unknown, message?: string): asserts value is Map<Key, Value> {
	if (!isNonEmptyMap(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty map', value));
	}
}

export function assertNonEmptyObject<Key extends keyof any = string, Value = unknown>(value: unknown, message?: string): asserts value is Record<Key, Value> {
	if (!isNonEmptyObject(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty object', value));
	}
}

export function assertNonEmptySet<T = unknown>(value: unknown, message?: string): asserts value is Set<T> {
	if (!isNonEmptySet(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty set', value));
	}
}

export function assertNonEmptyString(value: unknown, message?: string): asserts value is string {
	if (!isNonEmptyString(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty string', value));
	}
}

export function assertNonEmptyStringAndNotWhitespace(value: unknown, message?: string): asserts value is string {
	if (!isNonEmptyStringAndNotWhitespace(value)) {
		throw new TypeError(message ?? typeErrorMessage('non-empty string and not whitespace', value));

View on GitHub ↗ (pinned to 7821031c66)

Solutions

  1. Verify the object actually has keys — e.g. ensure the config file loaded and parsed correctly before asserting.
  2. If the value may legitimately be empty, branch on `is.nonEmptyObject(value)` instead of asserting.
  3. If holding a Map or Set, use `assert.nonEmptyMap`/`assert.nonEmptySet` instead — those are distinct checks.
  4. Remember only own enumerable string keys count; spread symbol/non-enumerable data into a plain object if needed.

Example fix

// before
const config = loadConfig() ?? {};
assert.nonEmptyObject(config); // throws on missing config file
// after
const config = loadConfig();
if (!is.nonEmptyObject(config)) {
  throw new Error('config.json is missing or empty — create it with at least one setting');
}
Defensive patterns

Strategy: validation

Validate before calling

if (is.object(value) && Object.keys(value).length > 0) {
  assert.nonEmptyObject(value);
}

Type guard

function isNonEmptyObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.keys(v).length > 0;
}

Try / catch

try {
  assert.nonEmptyObject(options);
} catch (error) {
  if (error instanceof TypeError) {
    // options is {}, null, or not a plain object — apply required defaults or reject
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `assert.nonEmptyObject(value)` with `{}`, `null`, an array, a Map/Set (their entries are not enumerable keys), or an object whose properties are all non-enumerable or symbol-keyed.

Common situations: Empty request bodies or config objects (`{}` from a missing JSON file or unset env-driven config); passing a Map thinking its size counts; destructured options objects defaulting to `{}`.

Related errors


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