cypress-io/cypress · error
The plugin register function must be called with a callback
Error message
The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'. What it means
Thrown by EventRegistrar.registerEvent when its second argument fails _.isFunction. After the string guard on event, the registrar verifies the callback is actually callable; passing a plain object, undefined, or a non-function value (e.g. forgetting to wrap a handler in an object for the 'task' event) triggers this guard.
Source
Thrown at packages/data-context/src/data/EventRegistrar.ts:37
const evtFn = this._registeredEvents[event]
if (typeof evtFn !== 'function') {
throw new Error(`Missing event for ${event}`)
}
return evtFn(...args)
}
registerEvent (event: string, callback: Function) {
debug(`register event '${event}'`)
if (!_.isString(event)) {
throw new Error(`The plugin register function must be called with an event as its 1st argument. You passed '${event}'.`)
}
if (!_.isFunction(callback)) {
throw new Error(`The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.`)
}
this._registeredEvents[event] = callback
}
reset () {
this._registeredEvents = {}
}
}
View on GitHub (pinned to 0d85fdc912)
Solutions
- Ensure the second argument to on() is a function (or for 'task' an object whose values are all functions).
- If importing a handler, verify the import is defined and is a function.
- Add a `typeof callback === 'function'` check in your plugin before on() if the handler is dynamically resolved.
- Inspect the echoed value in the error message — it shows exactly what was passed.
Example fix
// before
setupNodeEvents(on) { on('before:spec', { run: () => null }) } // object, not fn
// after
setupNodeEvents(on) { on('before:spec', () => null) } Defensive patterns
Strategy: type-guard
Validate before calling
function safeRegister (registrar, event, cb) {
if (typeof event !== 'string') throw new TypeError('event must be a string')
if (typeof cb !== 'function') throw new TypeError('callback must be a function')
registrar.registerEvent(event, cb)
} Type guard
function isHandler (v: unknown): v is Function {
return typeof v === 'function'
} Prevention
- Pass a function (or for 'task' an object of functions) as the callback.
- Verify imported handlers exist and are functions.
- Add typeof checks when handlers are resolved dynamically.
When it happens
Trigger: A plugin calls on('task', { foo: null }) (task handlers must be a map of functions but the registrar wraps it; passing a non-function at the top level fails), or on('before:spec', someObject) where someObject is not a function. Also when destructuring a handler from a module that does not export it.
Common situations: Forgetting the function wrapper around an event handler, passing a config object instead of a callback, or importing a handler that does not exist (undefined).
Related errors
- The plugin register function must be called with an event as
- Missing event for ${event}
- Invalid project path parameter: ${options.project}
- Unknown component name "${componentName}"
- No file name specified. This is required to generate a new C
AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12).
Data as JSON: /api/errors/98adb40d1d5ac47a.
Report an issue: GitHub.