{"record":{"id":"9f6f0933835b274f","repo":"jestjs/jest","slug":"invalid-first-argument-it-must-be-a-callback-func","errorCode":null,"errorMessage":"Invalid first argument. It must be a callback function.","messagePattern":"Invalid first argument\\. It must be a callback function\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/jest-jasmine2/src/jasmine/jasmineLight.ts","lineNumber":120,"sourceCode":"    fdescribe(description: string, specDefinitions: SpecDefinitionsFn) {\n      return env.fdescribe(description, specDefinitions);\n    },\n\n    it() {\n      return env.it.apply(env, arguments);\n    },\n\n    xit() {\n      return env.xit.apply(env, arguments);\n    },\n\n    fit() {\n      return env.fit.apply(env, arguments);\n    },\n\n    beforeEach() {\n      if (typeof arguments[0] !== 'function') {\n        throw new TypeError(\n          'Invalid first argument. It must be a callback function.',\n        );\n      }\n      return env.beforeEach.apply(env, arguments);\n    },\n\n    afterEach() {\n      if (typeof arguments[0] !== 'function') {\n        throw new TypeError(\n          'Invalid first argument. It must be a callback function.',\n        );\n      }\n      return env.afterEach.apply(env, arguments);\n    },\n\n    beforeAll() {\n      if (typeof arguments[0] !== 'function') {\n        throw new TypeError(","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-jasmine2/src/jasmine/jasmineLight.ts#L102-L138","documentation":"The global `beforeEach` (and the identically-guarded afterEach, beforeAll, afterAll) wrappers in the jasmine interface require their first argument to be a function. If a non-function is passed (string, number, undefined), the wrapper throws a TypeError at jasmineLight.ts:120 before delegating to env.beforeEach. This catches mistakes where the hook is called with no body or wrong argument.","triggerScenarios":"Calling `beforeEach()` with no arguments, `beforeEach('setup')`, or `beforeEach(undefined)`. The check `typeof arguments[0] !== 'function'` at jasmineLight.ts:119 triggers the throw. The same pattern guards afterEach (127), beforeAll (137), and afterAll (147).","commonSituations":"Writing `beforeEach` without a callback; passing a config object where the function was expected; a refactor that extracted the hook body into a variable that is undefined; calling `beforeEach(someFn())` instead of `beforeEach(someFn)`.","solutions":["Pass a function: `beforeEach(() => { ... })`.","If referencing a named function, pass the reference without invoking: `beforeEach(setup)` not `beforeEach(setup())`.","For async hooks, use `beforeEach(async () => { ... })` or `beforeEach((done) => { ... })`."],"exampleFix":"// before\nbeforeEach;  // missing call/callback\n// or\nbeforeEach(setup());\n// after\nbeforeEach(() => { /* ... */ });\n// or\nbeforeEach(setup);","handlingStrategy":"type-guard","validationCode":"// Guard all hook registrations.\nfunction safeBeforeEach(fn: unknown) {\n  if (typeof fn !== 'function') {\n    throw new TypeError(`beforeEach requires a callback function, got ${typeof fn}`);\n  }\n  return beforeEach(fn as () => void);\n}","typeGuard":"function isHookFn(value: unknown): value is () => void | Promise<void> {\n  return typeof value === 'function';\n}","tryCatchPattern":null,"preventionTips":["Always pass a function to beforeEach/afterEach/beforeAll/afterAll.","Pass function references without invoking them (no parentheses).","Use TypeScript so hook signatures require a function argument."],"tags":["beforeeach","hooks","typeerror","jasmine","api-misuse","validation"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}