cypress-io/cypress · error
Missing event for ${event}
Error message
Missing event for ${event} What it means
Thrown by EventRegistrar.executeNodeEvent when this._registeredEvents[event] is not a function. The registrar is the bridge that invokes plugin-registered event handlers (e.g. 'before:spec', 'task', 'file:preprocessor') from the plugins child process. Calling executeNodeEvent for an event that no plugin ever registered (or that was reset) hits this guard. It is a contract violation: the caller should have used isRegistered first, or the plugin failed to register the event.
Source
Thrown at packages/data-context/src/data/EventRegistrar.ts:23
export class EventRegistrar {
private _registeredEvents: Record<string, Function> = {}
hasNodeEvent (eventName: string) {
const isRegistered = typeof this._registeredEvents[eventName] === 'function'
debug('plugin event registered? %o', { eventName, isRegistered })
return isRegistered
}
executeNodeEvent (event: string, args: any[]) {
debug(`execute plugin event '${event}' Node '${process.version}' with args: %o %o %o`, ...args)
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
}View on GitHub (pinned to 0d85fdc912)
Solutions
- Check setupNodeEvents in cypress.config.ts: ensure `on('task', ...)` (or whichever event is failing) is reached without throwing.
- Wrap early setup in setupNodeEvents in try/catch and log so a registration-time error does not silently abort later registrations.
- If you call executeNodeEvent in your own tooling, guard with `if (registrar.isRegistered(event))` first.
- Run with DEBUG=cypress:plugins to see the event-registration log.
Example fix
// before
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
if (config.env.useTasks) on('task', { foo: () => null })
},
},
})
// caller invokes cy.task('foo') with useTasks=false -> error 56
// after
setupNodeEvents(on, config) {
on('task', { foo: () => null }) // always register if you may call it
} Defensive patterns
Strategy: type-guard
Validate before calling
function callIfRegistered (registrar, event, args) {
if (registrar.isRegistered(event)) {
return registrar.executeNodeEvent(event, args)
}
// silently skip or log
} Type guard
function isEventRegistered (registrar: { isRegistered: (e: string) => boolean }, event: string): boolean {
return registrar.isRegistered(event)
} Try / catch
try {
registrar.executeNodeEvent(event, args)
} catch (e) {
if (/Missing event for/.test(e.message)) {
// plugin never registered this event; degrade gracefully
return null
}
throw e
} Prevention
- Always guard executeNodeEvent with isRegistered.
- Ensure setupNodeEvents registers every event the server may invoke.
- Log inside setupNodeEvents so registration failures are visible.
When it happens
Trigger: Cypress server code calls executeNodeEvent('task', args) when no setupNodeEvents handler has called on('task', fn); or a plugin's setupNodeEvents threw before reaching the on('task', ...) registration line, leaving the event unregistered but the server still trying to invoke it.
Common situations: A user's setupNodeEvents threw an error during registration (so partial events were registered), a plugin is gated behind an env flag that was false, or internal server code is invoking an event before plugins finished loading.
Related errors
- The plugin register function must be called with an event as
- The plugin register function must be called with a callback
- cy.puppeteer() failed with the following error:\n> ${result.
- name should be a single string but got: ${from.query.name}
- params should be a string but got: ${from.query.params}
AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12).
Data as JSON: /api/errors/924ad68840b9fd9b.
Report an issue: GitHub.