{"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":"exception","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/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-jasmine2/src/jasmine/jasmineLight.ts#L102-L138","documentation":"Thrown by the jasmine2 `beforeEach` lifecycle wrapper in jasmineLight.ts:120 when its first argument is not a function. The wrapper guards `typeof arguments[0] !== 'function'` before delegating to `env.beforeEach`, so any non-callable first positional argument aborts the suite registration rather than producing a confusing downstream Jasmine failure. It exists because jasmine2 trusts the callback only after this check passes.","triggerScenarios":"Calling `beforeEach()` with zero arguments, `beforeEach('setup')` with a string description instead of a callback, `beforeEach({})`, or `beforeEach(async () => {}, someConfig)` where the callback was accidentally omitted and an object is in position 0.","commonSituations":"Refactoring a `beforeEach` body into a named helper but forgetting to wrap it in an arrow (`beforeEach(mySetup)` works, but `beforeEach(mySetup())` passes a non-function return value); copy-paste from `it('name', () => {})` into `beforeEach` and leaving the string in first position; transpilation/babel stripping the function.","solutions":["Ensure the first argument to `beforeEach` is a function reference or arrow function, e.g. `beforeEach(() => {...})`.","If you wrote `beforeEach('description', fn)`, drop the description string — jasmine2 lifecycle hooks do not take names.","If referencing a named helper, pass it uninvoked: `beforeEach(setup)` not `beforeEach(setup())`."],"exampleFix":"// before\nbeforeEach('set up db', db.connect)\n// after\nbeforeEach(() => db.connect())","handlingStrategy":"validation","validationCode":"if (typeof setup !== 'function') { throw new TypeError('beforeEach needs a function'); }\nbeforeEach(setup);","typeGuard":"const isHook = (fn: unknown): fn is (...a: any[]) => any => typeof fn === 'function';","tryCatchPattern":null,"preventionTips":["Lint for `beforeEach(` calls whose first arg is a string literal (likely a mistaken description).","Always pass an arrow function literal or a named function reference, never the result of an invocation."],"tags":["jasmine2","lifecycle","callback","before-each"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}