{"record":{"id":"924ad68840b9fd9b","repo":"cypress-io/cypress","slug":"missing-event-for-event","errorCode":null,"errorMessage":"Missing event for ${event}","messagePattern":"Missing event for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/data-context/src/data/EventRegistrar.ts","lineNumber":23,"sourceCode":"\nexport class EventRegistrar {\n  private _registeredEvents: Record<string, Function> = {}\n\n  hasNodeEvent (eventName: string) {\n    const isRegistered = typeof this._registeredEvents[eventName] === 'function'\n\n    debug('plugin event registered? %o', { eventName, isRegistered })\n\n    return isRegistered\n  }\n\n  executeNodeEvent (event: string, args: any[]) {\n    debug(`execute plugin event '${event}' Node '${process.version}' with args: %o %o %o`, ...args)\n\n    const evtFn = this._registeredEvents[event]\n\n    if (typeof evtFn !== 'function') {\n      throw new Error(`Missing event for ${event}`)\n    }\n\n    return evtFn(...args)\n  }\n\n  registerEvent (event: string, callback: Function) {\n    debug(`register event '${event}'`)\n\n    if (!_.isString(event)) {\n      throw new Error(`The plugin register function must be called with an event as its 1st argument. You passed '${event}'.`)\n    }\n\n    if (!_.isFunction(callback)) {\n      throw new Error(`The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.`)\n    }\n\n    this._registeredEvents[event] = callback\n  }","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/packages/data-context/src/data/EventRegistrar.ts#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nexport default defineConfig({\n  e2e: {\n    setupNodeEvents(on, config) {\n      if (config.env.useTasks) on('task', { foo: () => null })\n    },\n  },\n})\n// caller invokes cy.task('foo') with useTasks=false -> error 56\n// after\nsetupNodeEvents(on, config) {\n  on('task', { foo: () => null }) // always register if you may call it\n}","handlingStrategy":"type-guard","validationCode":"function callIfRegistered (registrar, event, args) {\n  if (registrar.isRegistered(event)) {\n    return registrar.executeNodeEvent(event, args)\n  }\n  // silently skip or log\n}","typeGuard":"function isEventRegistered (registrar: { isRegistered: (e: string) => boolean }, event: string): boolean {\n  return registrar.isRegistered(event)\n}","tryCatchPattern":"try {\n  registrar.executeNodeEvent(event, args)\n} catch (e) {\n  if (/Missing event for/.test(e.message)) {\n    // plugin never registered this event; degrade gracefully\n    return null\n  }\n  throw e\n}","preventionTips":["Always guard executeNodeEvent with isRegistered.","Ensure setupNodeEvents registers every event the server may invoke.","Log inside setupNodeEvents so registration failures are visible."],"tags":["plugins","events","task","internal"],"backgroundTag":null,"analyzedSha":"0d85fdc91230885bca0a91df278312800a48b727","analyzedAt":"2026-08-12T16:24:28.056Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}