{"id":"9ad86eaac9c2bfa7","repo":"vitest-dev/vitest","slug":"tohaveformvalues-must-be-called-with-an-object-of","errorCode":null,"errorMessage":"toHaveFormValues must be called with an object of expected form values. Got ${expectedValues}","messagePattern":"toHaveFormValues must be called with an object of expected form values\\. Got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/browser/src/client/tester/expect/toHaveFormValues.ts","lineNumber":35,"sourceCode":"import type { Locator } from '../locators'\nimport { cssEscape } from 'ivya/utils'\nimport { arrayAsSetComparison, getElementFromUserInput, getSingleElementValue, getTag } from './utils'\n\nexport default function toHaveFormValues(\n  this: MatcherState,\n  actual: Element | Locator,\n  expectedValues: Record<string, unknown>,\n): MatcherResult {\n  const formElement = getElementFromUserInput(actual, toHaveFormValues, this)\n\n  const defaultView = formElement.ownerDocument.defaultView || window\n\n  if (!(formElement instanceof defaultView.HTMLFieldSetElement) && !(formElement instanceof defaultView.HTMLFormElement)) {\n    throw new TypeError(`toHaveFormValues must be called on a form or a fieldset, instead got ${getTag(formElement)}`)\n  }\n\n  if (!expectedValues || typeof expectedValues !== 'object') {\n    throw new TypeError(\n      `toHaveFormValues must be called with an object of expected form values. Got ${expectedValues}`,\n    )\n  }\n\n  const formValues = getAllFormValues(formElement)\n  return {\n    pass: Object.entries(expectedValues).every(([name, expectedValue]) =>\n      this.equals(formValues[name], expectedValue, [arrayAsSetComparison, ...this.customTesters]),\n    ),\n    message: () => {\n      const to = this.isNot ? 'not to' : 'to'\n      const matcher = `${this.isNot ? '.not' : ''}.toHaveFormValues`\n\n      const commonKeyValues: Record<string, unknown> = {}\n      for (const key in formValues) {\n        if (!Object.hasOwn(expectedValues, key)) {\n          continue\n        }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/browser/src/client/tester/expect/toHaveFormValues.ts#L17-L53","documentation":"Thrown by `toHaveFormValues` at toHaveFormValues.ts:34-37 when the second argument is not a non-null object. The matcher signature requires `Record<string, unknown>`; passing `undefined`, `null`, a primitive, an array, or omitting the argument entirely fails the `typeof expectedValues !== 'object'` guard.","triggerScenarios":"Calling `expect(form).toHaveFormValues()` (no second arg), `expect(form).toHaveFormValues(null)`, `expect(form).toHaveFormValues('email')`, or `expect(form).toHaveFormValues(['email'])`. Also triggered by passing a value typed `any` that is actually a string at runtime.","commonSituations":"Migrating from `toHaveValue` and assuming the second arg is a string. Constructing expected values from a function that can return `undefined`. JavaScript users (no TS compile-time check) passing the wrong shape.","solutions":["Pass a plain object mapping field names to expected values: `expect(form).toHaveFormValues({ email: 'a@b.com', count: 2 })`.","If building expected values dynamically, default to `{}` instead of `undefined`: `expect(form).toHaveFormValues(expected ?? {})`.","Add a TypeScript annotation (`const expected: Record<string, unknown> = ...`) so the compiler catches the mismatch."],"exampleFix":"// before\nexpect(form).toHaveFormValues(buildExpected()) // buildExpected() may return undefined\n\n// after\nconst expected = buildExpected() ?? {}\nexpect(form).toHaveFormValues(expected)","handlingStrategy":"validation","validationCode":"function isValuesObject(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === 'object' && !Array.isArray(v)\n}\nconst safe = isValuesObject(expected) ? expected : {}","typeGuard":"function isValuesObject(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === 'object' && !Array.isArray(v)\n}","tryCatchPattern":null,"preventionTips":["Annotate expected values as Record<string, unknown> so TS rejects wrong types.","Default to {} when building expected values from optional sources.","Review the matcher signature before use: second arg is always an object."],"tags":["browser","expect-matcher","tohaveformvalues","argument-validation","typescript"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}