{"record":{"id":"3b4ea898a8b6a941","repo":"jestjs/jest","slug":"primitives-cannot-leak-memory-you-passed-a-type","errorCode":null,"errorMessage":"Primitives cannot leak memory. You passed a ${typeof value}: <${prettyFormat(value)}>","messagePattern":"Primitives cannot leak memory\\. You passed a (.+?): <(.+?)>","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/jest-leak-detector/src/index.ts","lineNumber":28,"sourceCode":"import {getHeapSnapshot, setFlagsFromString} from 'node:v8';\nimport {runInNewContext} from 'node:vm';\nimport {isPrimitive} from '@jest/get-type';\nimport {format as prettyFormat} from 'pretty-format';\n\ninterface LeakDetectorOptions {\n  shouldGenerateV8HeapSnapshot: boolean;\n}\n\nconst tick = promisify(setImmediate);\n\nexport default class LeakDetector {\n  private _isReferenceBeingHeld: boolean;\n  private _shouldGenerateV8HeapSnapshot: boolean;\n  private readonly _finalizationRegistry?: FinalizationRegistry<undefined>;\n\n  constructor(value: unknown, opt?: LeakDetectorOptions) {\n    if (isPrimitive(value)) {\n      throw new TypeError(\n        [\n          'Primitives cannot leak memory.',\n          `You passed a ${typeof value}: <${prettyFormat(value)}>`,\n        ].join(' '),\n      );\n    }\n\n    // When `_finalizationRegistry` is GCed the callback we set will no longer be called,\n    this._finalizationRegistry = new FinalizationRegistry(() => {\n      this._isReferenceBeingHeld = false;\n    });\n    this._finalizationRegistry.register(value as object, undefined);\n\n    this._isReferenceBeingHeld = true;\n\n    this._shouldGenerateV8HeapSnapshot =\n      opt?.shouldGenerateV8HeapSnapshot ?? true;\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-leak-detector/src/index.ts#L10-L46","documentation":"Thrown by jest-leak-detector's LeakDetector constructor when the value passed is a primitive (index.ts:27-34). Memory-leak detection relies on a FinalizationRegistry that only tracks object references; primitives (string, number, boolean, symbol, bigint, null, undefined) cannot be held by reference and therefore cannot leak, so the constructor refuses them.","triggerScenarios":"new LeakDetector(42), new LeakDetector('hello'), new LeakDetector(null), or new LeakDetector(true). Also when a value that is expected to be an object turns out to be a primitive at runtime (e.g. a function returned a string instead of an instance).","commonSituations":"Writing custom leak tests and passing a config value instead of the instance; jest-jasmine2 leak detection enabled (--detect-leaks) on a test whose subject is a primitive; helper functions that lose object-ness via serialisation; API change where a factory now returns a primitive token.","solutions":["Wrap the primitive in an object: new LeakDetector({value: primitive}).","Verify the subject is an object before constructing: if (!isPrimitive(subject)) new LeakDetector(subject).","If using --detect-leaks, ensure your exports are objects/classes, not bare primitives.","Debug what value is being passed by logging typeof before constructing."],"exampleFix":"// before\nnew LeakDetector(getToken()); // getToken() returns a string\n// after\nconst token = getToken();\nnew LeakDetector({token}); // wrap in object","handlingStrategy":"type-guard","validationCode":"import {isPrimitive} from '@jest/get-type';\nif (isPrimitive(value)) {\n  throw new TypeError('LeakDetector requires an object reference, not a primitive');\n}\nnew LeakDetector(value);","typeGuard":"const isObjectReference = (v: unknown): v is object =>\n  v !== null && (typeof v === 'object' || typeof v === 'function');","tryCatchPattern":null,"preventionTips":["Wrap primitives in objects before leak-detecting.","Confirm the factory returns an instance, not a token.","Guard with isPrimitive before constructing."],"tags":["jest","leak-detector","primitive","memory","type-error"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}