vitest-dev/vitest · error
invalid export in globalSetup file
Error message
invalid export in globalSetup file ${file}: ${exp} must be a function What it means
loadGlobalSetupFile requires each of default/setup/teardown exports to be a function IF present (non-null). If an export is non-null but not a function (a constant, object, number), it throws. This enforces the globalSetup callable contract before invocation.
Solutions
- Make the export a function: `export function setup() { ... }` or `export default function() { ... }`.
- Remove the export if it wasn't meant to be a setup/teardown hook.
- Check for naming collisions where setup/teardown is shadowed by a constant.
Example fix
// before
export const setup = { init: () => db.connect() }
// after
export function setup() {
db.connect()
} Defensive patterns
Strategy: type-guard
Validate before calling
function exportsAreFunctions(mod, keys = ['default', 'setup', 'teardown']) {
return keys.every(k => mod[k] == null || typeof mod[k] === 'function')
} Type guard
function isFunctionExport(mod, key): boolean {
return mod[key] == null || typeof mod[key] === 'function'
} Prevention
- Keep globalSetup exports as functions only.
- Lint globalSetup files to reject non-function named exports for setup/teardown/default.
- Avoid name collisions between constants and the setup/teardown hooks.
When it happens
Trigger: A globalSetup file exporting default/setup/teardown as a non-function value (number, object, string, array). For example `export const setup = { foo: 1 }`.
Common situations: Mistyped export; named-export collision; default-exporting a config object instead of a function; refactor that changed an export's shape.
Related errors
- invalid globalSetup file
- expects the actual value to be a benchmark result.
- expects the expected value to be a benchmark result.
- expects the actual value to be a benchmark result.
- expects the expected value to be a benchmark result.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/2d50f13e90d7f6ee.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/node/globalSetup.ts:28
export async function loadGlobalSetupFiles(
runner: ModuleRunner,
globalSetup: string | string[],
): Promise<GlobalSetupFile[]> {
const globalSetupFiles = toArray(globalSetup)
return Promise.all(
globalSetupFiles.map(file => loadGlobalSetupFile(file, runner)),
)
}
async function loadGlobalSetupFile(
file: string,
runner: ModuleRunner,
): Promise<GlobalSetupFile> {
const m = await runner.import(file)
for (const exp of ['default', 'setup', 'teardown']) {
if (m[exp] != null && typeof m[exp] !== 'function') {
throw new Error(
`invalid export in globalSetup file ${file}: ${exp} must be a function`,
)
}
}
if (m.default) {
return {
file,
setup: m.default,
}
}
else if (m.setup || m.teardown) {
return {
file,
setup: m.setup,
teardown: m.teardown,
}
}
else {View on GitHub (pinned to 1fa9837ec2)