awslabs/llrt · error · TypeError

You must provide an object to

Error message

You must provide an object to ${this.toString()}, not '${typeof this.sample}'.

What it means

ObjectContaining.asymmetricMatch validates its own sample each time it matches. If the sample given to expect.objectContaining(...) was not an object (e.g. a string, number, or undefined), it throws this TypeError during matching rather than producing a wrong result. The message interpolates the matcher name and the actual typeof of the bad sample.

Solutions

  1. Pass a plain object of expected properties: expect.objectContaining({ id: 1 }).
  2. Check that the variable holding the sample is not undefined/null at match time.
  3. Use expect.anything() or expect.any(Type) for non-object matching needs.
  4. Wrap nested matchers correctly — nested samples must themselves be objects.

Example fix

// before
expect(user).toEqual(expect.objectContaining('name'));
// after
expect(user).toEqual(expect.objectContaining({ name: expect.any(String) }));
Defensive patterns

Strategy: type-guard

Validate before calling

if (sample === null || typeof sample !== 'object' || Array.isArray(sample)) throw new TypeError('objectContaining sample must be a plain object');

Type guard

const isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);

Try / catch

try { expect(v).toEqual(expect.objectContaining(spec)); } catch (e) { /* log and fall back to a plain toEqual assertion */ }

Prevention

When it happens

Trigger: expect.objectContaining(42), expect.objectContaining('foo'), or expect.objectContaining(undefined) — the throw happens when the matcher is actually applied to a value, not at construction.

Common situations: Passing a JSON-decoded value that turned out to be a scalar, passing an array where an object was intended, or calling objectContaining() with no arguments (sample undefined) after a refactor.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12). Data as JSON: /api/errors/4064c34ed7069683. Report an issue: GitHub.

Appendix: source

Thrown at llrt_core/src/modules/js/@llrt/expect/jest-asymmetric-matchers.ts:142

  getPrototype(obj: object) {
    if (Object.getPrototypeOf) return Object.getPrototypeOf(obj);

    if (obj.constructor.prototype === obj) return null;

    return obj.constructor.prototype;
  }

  hasProperty(obj: object | null, property: string): boolean {
    if (!obj) return false;

    if (Object.prototype.hasOwnProperty.call(obj, property)) return true;

    return this.hasProperty(this.getPrototype(obj), property);
  }

  asymmetricMatch(other: any) {
    if (typeof this.sample !== "object") {
      throw new TypeError(
        `You must provide an object to ${this.toString()}, not '${typeof this
          .sample}'.`
      );
    }

    let result = true;

    // const matcherContext = this.getMatcherContext()
    for (const property in this.sample) {
      if (
        !this.hasProperty(other, property) ||
        !equals(this.sample[property], other[property], [])
      ) {
        result = false;
        break;
      }
    }

View on GitHub (pinned to 742fc00b82)