jestjs/jest · error · TypeError

Invalid first argument. It must be a callback function.

Error message

Invalid first argument. It must be a callback function.

What it means

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.

Source

Thrown at packages/jest-jasmine2/src/jasmine/jasmineLight.ts:120

    fdescribe(description: string, specDefinitions: SpecDefinitionsFn) {
      return env.fdescribe(description, specDefinitions);
    },

    it() {
      return env.it.apply(env, arguments);
    },

    xit() {
      return env.xit.apply(env, arguments);
    },

    fit() {
      return env.fit.apply(env, arguments);
    },

    beforeEach() {
      if (typeof arguments[0] !== 'function') {
        throw new TypeError(
          'Invalid first argument. It must be a callback function.',
        );
      }
      return env.beforeEach.apply(env, arguments);
    },

    afterEach() {
      if (typeof arguments[0] !== 'function') {
        throw new TypeError(
          'Invalid first argument. It must be a callback function.',
        );
      }
      return env.afterEach.apply(env, arguments);
    },

    beforeAll() {
      if (typeof arguments[0] !== 'function') {
        throw new TypeError(

View on GitHub (pinned to f49721c78e)

Solutions

  1. Ensure the first argument to `beforeEach` is a function reference or arrow function, e.g. `beforeEach(() => {...})`.
  2. If you wrote `beforeEach('description', fn)`, drop the description string — jasmine2 lifecycle hooks do not take names.
  3. If referencing a named helper, pass it uninvoked: `beforeEach(setup)` not `beforeEach(setup())`.

Example fix

// before
beforeEach('set up db', db.connect)
// after
beforeEach(() => db.connect())
Defensive patterns

Strategy: validation

Validate before calling

if (typeof setup !== 'function') { throw new TypeError('beforeEach needs a function'); }
beforeEach(setup);

Type guard

const isHook = (fn: unknown): fn is (...a: any[]) => any => typeof fn === 'function';

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/9f6f0933835b274f.json. Report an issue: GitHub.