jestjs/jest · error · Error
expected path must be a string or array
Error message
expected path must be a string or array
What it means
Thrown by `toHaveProperty` (matchers.ts:711) when the first argument (the key path) is neither a string nor an array. `toHaveProperty` accepts a dot/bracket string (`'a.b[0].c'`) or an array of keys (`['a', 'b', '0', 'c']`); any other type (number, object, null) cannot be traversed. The check uses `getType(expectedPath)` and rejects anything whose type isn't `'string'` or `'array'`.
Source
Thrown at packages/expect/src/matchers.ts:738
isNot: this.isNot,
promise: this.promise,
secondArgument: hasValue ? 'value' : '',
};
if (received === null || received === undefined) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, expectedArgument, options),
`${RECEIVED_COLOR('received')} value must not be null nor undefined`,
printWithType('Received', received, printReceived),
),
);
}
const expectedPathType = getType(expectedPath);
if (expectedPathType !== 'string' && expectedPathType !== 'array') {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, expectedArgument, options),
`${EXPECTED_COLOR('expected')} path must be a string or array`,
printWithType('Expected', expectedPath, printExpected),
),
);
}
const expectedPathLength =
typeof expectedPath === 'string'
? pathAsArray(expectedPath).length
: expectedPath.length;
if (expectedPathType === 'array' && expectedPathLength === 0) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, expectedArgument, options),
`${EXPECTED_COLOR('expected')} path must not be an empty array`,View on GitHub (pinned to f49721c78e)
Solutions
- Convert the path to a string: `.toHaveProperty(String(key))`.
- Use the array form for clarity: `.toHaveProperty([String(key)])`.
- Log `typeof expectedPath` and `Array.isArray(expectedPath)` to confirm shape.
- If the path comes from a dynamic source, validate it before the test.
Example fix
// before expect(arr).toHaveProperty(index); // index is a number // after expect(arr).toHaveProperty(String(index));
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof path !== 'string' && !Array.isArray(path)) {
throw new Error(`path must be string or array, got ${typeof path}`);
}
expect(obj).toHaveProperty(path); Type guard
const isPath = (v: unknown): v is string | Array<unknown> => typeof v === 'string' || Array.isArray(v);
Try / catch
try {
expect(obj).toHaveProperty(path);
} catch (e) {
if (e instanceof Error && /path must be a string or array/.test(e.message)) {
console.error('path was', typeof path, path);
}
throw e;
} Prevention
- Wrap numeric keys as strings: `String(index)`.
- Use the array form `[a, b]` for clarity with computed keys.
- Validate dynamic paths before constructing the assertion.
When it happens
Trigger: Calling `expect(obj).toHaveProperty(42)` (number), `.toHaveProperty({key: 'a'})` (object), `.toHaveProperty(null)`, `.toHaveProperty(true)`, or passing a Symbol. Note: a single-key string is valid, but a raw number like an array index is not — it must be `'42'` or `['42']`.
Common situations: Passing a computed numeric key directly instead of wrapping as string; passing a path object from a helper library; refactor that changed a path variable from string to number; copy-paste from a different matcher API.
Related errors
- expected value must be a string if received value is a strin
- received value must be a string
- expected value must be a string or regular expression
- expected value must be a number
- received value must be a number
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/ef83bff8258e7dda.json.
Report an issue: GitHub.