jestjs/jest · error · Error
Cannot use spyOn on a primitive value; ${this._typeOf(object
Error message
Cannot use spyOn on a primitive value; ${this._typeOf(object)} given What it means
Thrown by jest.spyOn when the first argument is null, undefined, or a JS primitive (number/string/boolean/symbol). spyOn can only attach a spy to an object or function, so the guard rejects non-object targets up front.
Source
Thrown at packages/jest-mock/src/index.ts:1280
spyOn<
T extends object,
K extends ConstructorLikeKeys<T> | MethodLikeKeys<T>,
V extends Required<T>[K],
>(
object: T,
methodKey: K,
): V extends ClassLike | FunctionLike ? Spied<V> : never;
spyOn<T extends object>(
object: T,
methodKey: keyof T,
accessType?: 'get' | 'set',
): MockInstance {
if (
object == null ||
(typeof object !== 'object' && typeof object !== 'function')
) {
throw new Error(
`Cannot use spyOn on a primitive value; ${this._typeOf(object)} given`,
);
}
if (methodKey == null) {
throw new Error('No property name supplied');
}
if (accessType) {
return this._spyOnProperty(object, methodKey, accessType);
}
const original = object[methodKey];
if (!original) {
throw new Error(
`Property \`${String(
methodKey,View on GitHub (pinned to 8e6d128e4a)
Solutions
- Log the first argument to confirm it is an object/function at runtime.
- Fix the import (named vs default, correct relative path, check the module's exports field).
- Spy on the object that owns the method (e.g. the module namespace object) rather than a primitive it exports.
Example fix
// before jest.spyOn(logger, 'info'); // logger is undefined because of wrong import // after import * as logger from './logger'; jest.spyOn(logger, 'info');
Defensive patterns
Strategy: type-guard
Validate before calling
if (target == null || (typeof target !== 'object' && typeof target !== 'function')) {
throw new TypeError(`spyOn target must be an object/function, got ${typeof target}`);
}
jest.spyOn(target, methodName); Type guard
const isSpyable = (x: unknown): x is object => x != null && (typeof x === 'object' || typeof x === 'function');
Prevention
- Log the import you intend to spy on before calling spyOn.
- Prefer spying on module namespace objects (import * as) for stable references.
- Verify named vs default exports match your import style.
When it happens
Trigger: jest.spyOn(null,'foo'); jest.spyOn(undefined,'bar'); jest.spyOn('hello','length'); jest.spyOn(42,'toString'); jest.spyOn(true,'valueOf').
Common situations: The module/object import resolved to undefined (wrong path, named/default mismatch, ESM vs CJS interop); spying on a re-export that lost the object; tree-shaking removed the binding; passing a destructured primitive instead of the holder object.
Related errors
- Cannot spy on the `${String(methodKey)}` property because it
- ${RECEIVED_COLOR('received')} value must be a mock or spy fu
- ${RECEIVED_COLOR('received')} value must be a mock function
- ${EXPECTED_COLOR('expected')} value must be a non-negative i
- No property name supplied
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/3c0642d4c11567be.
Report an issue: GitHub.