{"record":{"id":"e2e7d0a85931934e","repo":"cypress-io/cypress","slug":"the-plugin-register-function-must-be-called-with-a","errorCode":null,"errorMessage":"The plugin register function must be called with an event as its 1st argument. You passed '${event}'.","messagePattern":"The plugin register function must be called with an event as its 1st argument\\. You passed '(.+?)'\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/data-context/src/data/EventRegistrar.ts","lineNumber":33,"sourceCode":"  }\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  }\n\n  reset () {\n    this._registeredEvents = {}\n  }\n}\n","sourceCodeStart":15,"sourceCodeEnd":47,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/packages/data-context/src/data/EventRegistrar.ts#L15-L47","documentation":"Thrown by EventRegistrar.registerEvent when its first argument fails _.isString. The registrar expects plugin authors to call on(eventName, callback) where eventName is a known event name string; passing undefined, a number, null, or an object triggers this guard. The error message echoes the offending value so the plugin author can see what they passed.","triggerScenarios":"A plugin's setupNodeEvents calls on(undefined, fn) (typically because the event name was misspelled or destructured from a non-existent export), or a plugin passes a numeric/object identifier. Often the result of `const { BeforeSpec } = ...` destructuring that returned undefined.","commonSituations":"Typo in event name variable, importing an event-name constant that does not exist (undefined), or third-party plugin calling on() with a computed value that evaluates to a non-string.","solutions":["Inspect the value passed as the first argument to on() — it must be a string literal like 'before:spec' or 'task'.","If using an imported constant, verify the import resolves (it is likely undefined).","Add a typeof check before calling on() in your plugin if the event name is dynamic.","Run with DEBUG=cypress:plugins to see the register-event log line that includes the value."],"exampleFix":"// before\nimport { WrongName } from 'some-pkg'\nsetupNodeEvents(on) { on(WrongName, () => null) } // WrongName is undefined\n// after\nsetupNodeEvents(on) { on('before:spec', () => null) }","handlingStrategy":"type-guard","validationCode":"function safeRegister (registrar, event, cb) {\n  if (typeof event !== 'string' || !event) {\n    throw new TypeError(`event must be a non-empty string, got ${typeof event}`)\n  }\n  registrar.registerEvent(event, cb)\n}","typeGuard":"function isEventName (v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0\n}","tryCatchPattern":null,"preventionTips":["Use string literals for event names.","Verify imported event-name constants are defined before passing.","Add a typeof check in plugin code if names are dynamic."],"tags":["plugins","events","validation","api-contract"],"backgroundTag":null,"analyzedSha":"0d85fdc91230885bca0a91df278312800a48b727","analyzedAt":"2026-08-12T16:24:28.056Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}