{"record":{"id":"23840cabb1432398","repo":"vitest-dev/vitest","slug":"tohaveproperty-expects-to-receive-a-valid-objec","errorCode":null,"errorMessage":".toHaveProperty() expects to receive a valid object, but got ${actual}","messagePattern":"\\.toHaveProperty\\(\\) expects to receive a valid object, but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/expect/src/jest-expect.ts","lineNumber":471,"sourceCode":"  def('toBeInstanceOf', function (obj: any) {\n    return this.instanceOf(obj)\n  })\n  def('toHaveLength', function (length: number) {\n    return this.have.length(length)\n  })\n  // destructuring, because it checks `arguments` inside, and value is passing as `undefined`\n  def(\n    'toHaveProperty',\n    function (...args: [property: string | (string | number)[], value?: any]) {\n      if (Array.isArray(args[0])) {\n        args[0] = args[0]\n          .map(key => String(key).replace(/([.[\\]])/g, '\\\\$1'))\n          .join('.')\n      }\n\n      const actual = this._obj as any\n      if (actual == null) {\n        throw new TypeError(\n          `.toHaveProperty() expects to receive a valid object, but got ${actual}`,\n        )\n      }\n      const [propertyName, expected] = args\n      const getValue = () => {\n        const hasOwn = Object.hasOwn(\n          actual,\n          propertyName,\n        )\n        if (hasOwn) {\n          return { value: actual[propertyName], exists: true }\n        }\n        return utils.getPathInfo(actual, propertyName)\n      }\n      const { value, exists } = getValue()\n      const pass\n        = exists\n          && (args.length === 1 || jestEquals(expected, value, customTesters))","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/expect/src/jest-expect.ts#L453-L489","documentation":"Thrown by the `toHaveProperty` matcher when the value passed to `expect()` is `null` or `undefined`. The matcher needs a real object to look up a property path on, so it refuses to operate on a missing receiver. This is a hard `TypeError` raised before any property lookup is attempted.","triggerScenarios":"Calling `expect(null).toHaveProperty('foo')` or `expect(undefined).toHaveProperty('a.b')`, including when a lookup function or selector returned nothing and the result was passed straight into `expect()`.","commonSituations":"Querying a DOM element or config object that does not exist (returns null); reading an optional API field that was absent; destructuring from a possibly-absent response without a default; async value that resolved to undefined.","solutions":["Guard the value before asserting: only call `toHaveProperty` when the value is non-null.","If absence is expected, use `toBe(null)` / `toBeUndefined()` instead of `toHaveProperty`.","Fix the upstream producer so it returns an object (e.g. add a fallback `{}`) instead of null.","For optional chains, assert on the nested value directly with `toBeUndefined()`."],"exampleFix":"// before\nexpect(user.profile).toHaveProperty('email')\n\n// after\nexpect(user.profile).not.toBeNull()\nexpect(user.profile).toHaveProperty('email')","handlingStrategy":"type-guard","validationCode":"if (value == null) { throw new Error(`cannot assert properties on ${value}`) }\nexpect(value).toHaveProperty('foo')","typeGuard":"const isRecord = (v: unknown): v is Record<string, unknown> =>\n  v !== null && typeof v === 'object'","tryCatchPattern":null,"preventionTips":["Always confirm the value is non-null before calling toHaveProperty.","Use optional chaining in the producer so undefined never reaches expect.","Prefer asserting absence explicitly with toBeUndefined when null is valid."],"tags":["expect","assertion","null-check","jest-expect"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}