mochajs/mocha · error · Error
ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION
ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION
Error message
mochaHooks must be an object or a function returning (or fulfilling with) an object
What it means
The plugin loader's `mochaHooks` definition validate() (lib/plugin-loader.js:44) throws ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION when a root hook implementation is neither a function nor a plain object (arrays are explicitly rejected). mochaHooks must be an object of hook arrays/functions or a function returning (or fulfilling with) such an object.
Source
Thrown at lib/plugin-loader.js:44
*/
/**
* Built-in plugin definitions.
*/
const MochaPlugins = [
/**
* Root hook plugin definition
* @type {PluginDefinition}
*/
{
exportName: "mochaHooks",
optionName: "rootHooks",
validate(value) {
if (
Array.isArray(value) ||
(typeof value !== "function" && typeof value !== "object")
) {
throw createInvalidPluginImplementationError(
`mochaHooks must be an object or a function returning (or fulfilling with) an object`,
);
}
},
async finalize(rootHooks) {
if (rootHooks.length) {
const rootHookObjects = await Promise.all(
rootHooks.map(async (hook) =>
typeof hook === "function" ? hook() : hook,
),
);
return rootHookObjects.reduce(
(acc, hook) => {
hook = {
beforeAll: [],
beforeEach: [],
afterAll: [],View on GitHub (pinned to 6bcbee4fd9)
Solutions
- Export `mochaHooks` as an object keyed by hook name, e.g. `exports.mochaHooks = { beforeEach: [ ... ] }`.
- If a function, make it return (or fulfill with) a hooks object.
- If you have an array, convert it to an object like `{ beforeEach: [...] }`.
- Verify the `rootHooks` config path points to the intended module.
Example fix
// before
exports.mochaHooks = [beforeEachHook, afterEachHook];
// after
exports.mochaHooks = { beforeEach: [beforeEachHook], afterEach: [afterEachHook] }; Defensive patterns
Strategy: validation
Validate before calling
const hooks = require('./global-hooks');
const v = hooks.mochaHooks;
const ok = !Array.isArray(v) && (typeof v === 'function' || typeof v === 'object' && v !== null);
if (!ok) throw new Error('mochaHooks must be an object or function returning an object'); Type guard
function isValidMochaHooks(v) {
return !Array.isArray(v) && (typeof v === 'function' || (typeof v === 'object' && v !== null));
} Try / catch
try {
await mocha.loadRootHooks();
} catch (err) {
if (err.code === 'ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION') {
console.error('Fix exports.mochaHooks shape: object or function returning object');
} else throw err;
} Prevention
- Export mochaHooks as { beforeEach: [...], afterEach: [...] }
- Never export arrays for rootHooks
- Verify module path in .mocharc rootHooks option
When it happens
Trigger: Exporting `mochaHooks` as an array (e.g. `[beforeEach, afterEach]`), as a string/number, or forgetting to export it correctly so the loader receives the wrong type; also when an async factory returns something other than an object.
Common situations: Config in `.mocharc` `rootHooks` pointing at a module whose default export shape changed; migrating from arrays of hooks to the mochaHooks object convention; TypeScript files exporting hooks in the wrong shape.
Related errors
AI-assisted analysis of mochajs/mocha@6bcbee4fd9 (2026-09-01).
Data as JSON: /api/errors/195e05620abf82e9.
Report an issue: GitHub.