jestjs/jest · error · TypeError

received value must have a length property whose value must

Error message

received value must have a length property whose value must be a number

What it means

Thrown by `toHaveLength` (matchers.ts:656) when the received value either has no `.length` property, or its `.length` is not a number. The matcher reads `received.length` and compares it via `===` to the expected integer, so a missing or non-numeric length breaks the comparison. The check uses optional chaining (`received?.length`) so null/undefined received values also surface here rather than crashing.

Source

Thrown at packages/expect/src/matchers.ts:665

            isExpand(this.expand),
          );

    // Passing the actual and expected objects so that a custom reporter
    // could access them, for example in order to display a custom visual diff,
    // or create a different error message
    return {actual: received, expected, message, name: matcherName, pass};
  },

  toHaveLength(received: any, expected: number) {
    const matcherName = 'toHaveLength';
    const isNot = this.isNot;
    const options: MatcherHintOptions = {
      isNot,
      promise: this.promise,
    };

    if (typeof received?.length !== 'number') {
      throw new TypeError(
        matcherErrorMessage(
          matcherHint(matcherName, undefined, undefined, options),
          `${RECEIVED_COLOR(
            'received',
          )} value must have a length property whose value must be a number`,
          printWithType('Received', received, printReceived),
        ),
      );
    }

    ensureExpectedIsNonNegativeInteger(expected, matcherName, options);

    const pass = received.length === expected;

    const message = () => {
      const labelExpected = 'Expected length';
      const labelReceivedLength = 'Received length';
      const labelReceivedValue = `Received ${getType(received)}`;

View on GitHub (pinned to f49721c78e)

Solutions

  1. If checking a Map/Set, use `.size` and assert on `map.size` directly or convert: `expect([...map]).toHaveLength(3)`.
  2. For objects, assert on keys: `expect(Object.keys(obj)).toHaveLength(3)`.
  3. Confirm the received value is the iterable you expect — log `received` and `typeof received?.length`.
  4. If nullish is possible, guard or fix the producer to return `[]`.

Example fix

// before
expect(user.permissions).toHaveLength(3); // Map, no .length

// after
expect([...user.permissions]).toHaveLength(3);
Defensive patterns

Strategy: type-guard

Validate before calling

if (received == null || typeof received.length !== 'number') {
  throw new Error(`received must have a numeric .length, got ${received == null ? String(received) : 'no length'}`);
}
expect(received).toHaveLength(n);

Type guard

const hasNumericLength = (v: unknown): v is {length: number} =>
  v != null && typeof (v as any).length === 'number';

Try / catch

try {
  expect(received).toHaveLength(n);
} catch (e) {
  if (e instanceof TypeError && /length property/.test(e.message)) {
    console.error('received has no numeric length; received:', received);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `expect(value).toHaveLength(3)` where `value` is a plain object without `length` (`{a:1}`), a number, a boolean, `null`/`undefined`, or an object whose `length` is a string (e.g. some jQuery-like wrappers).

Common situations: Asserting length on a Map/Set (they have `.size`, not `.length`); on a Promise; on a function reference before invocation; on `null` from a failed query; mixing up `Object.keys(obj).length` (works) with checking `obj` directly.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/54a7d38959aecae7.json. Report an issue: GitHub.