jestjs/jest · error · TypeError

${moduleName} file must export a function at ${modulePath}

Error message

${moduleName} file must export a function at ${modulePath}

What it means

runGlobalHook loads each configured globalSetup/globalTeardown module via the script transformer and expects its default export (or module.exports) to be a function. If the module exports an object, a string, or nothing, this TypeError is thrown naming the module path. The function receives (globalConfig, projectConfig).

Source

Thrown at packages/jest-core/src/runGlobalHook.ts:53

      }

      const correctConfig = allTests.find(
        t => t.context.config[moduleName] === modulePath,
      );

      const projectConfig = correctConfig
        ? correctConfig.context.config
        : // Fallback to first config
          allTests[0].context.config;

      const transformer = await createScriptTransformer(projectConfig);

      try {
        await transformer.requireAndTranspileModule(
          modulePath,
          async globalModule => {
            if (typeof globalModule !== 'function') {
              throw new TypeError(
                `${moduleName} file must export a function at ${modulePath}`,
              );
            }

            await globalModule(globalConfig, projectConfig);
          },
        );
      } catch (error) {
        if (
          isError(error) &&
          (Object.getOwnPropertyDescriptor(error, 'message')?.writable ||
            Object.getOwnPropertyDescriptor(
              Object.getPrototypeOf(error),
              'message',
            )?.writable)
        ) {
          error.message = `Jest: Got error running ${moduleName} - ${modulePath}, reason: ${error.message}`;

View on GitHub (pinned to f49721c78e)

Solutions

  1. Make the globalSetup/globalTeardown file export a function as default: export default async (globalConfig, projectConfig) => {...}
  2. For CommonJS: module.exports = async (globalConfig, projectConfig) => {...}
  3. Verify there is no accidental named-only export or object export

Example fix

// before
export default { setup: () => { /*...*/ } };
// after
export default async (globalConfig, projectConfig) => { /*...*/ };
Defensive patterns

Strategy: type-guard

Validate before calling

function assertFunctionExport(m: unknown): asserts m is Function {
  if (typeof m !== 'function') {
    throw new TypeError('globalSetup/globalTeardown must default-export a function');
  }
}

Type guard

function isGlobalHookExport(m: unknown): m is (g: unknown, p: unknown) => unknown | Promise<unknown> {
  return typeof m === 'function';
}

Prevention

When it happens

Trigger: A globalSetup file that does `export default {...}` instead of `export default function(...) {...}`; a module with only named exports; a file that forgot to export anything.

Common situations: Converting a config-object file into a globalSetup but forgetting to change the export; a refactor that drops the default export; CommonJS/ESM interop returning the module namespace instead of the function.

Related errors


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