{"record":{"id":"98adb40d1d5ac47a","repo":"cypress-io/cypress","slug":"the-plugin-register-function-must-be-called-with-a-98adb4","errorCode":null,"errorMessage":"The plugin register function must be called with a callback function as its 2nd argument. You passed '${callback}'.","messagePattern":"The plugin register function must be called with a callback function as its 2nd argument\\. You passed '(.+?)'\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/data-context/src/data/EventRegistrar.ts","lineNumber":37,"sourceCode":"\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":19,"sourceCodeEnd":47,"githubUrl":"https://github.com/cypress-io/cypress/blob/0d85fdc91230885bca0a91df278312800a48b727/packages/data-context/src/data/EventRegistrar.ts#L19-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nsetupNodeEvents(on) { on('before:spec', { run: () => null }) } // object, not fn\n// after\nsetupNodeEvents(on) { on('before:spec', () => null) }","handlingStrategy":"type-guard","validationCode":"function safeRegister (registrar, event, cb) {\n  if (typeof event !== 'string') throw new TypeError('event must be a string')\n  if (typeof cb !== 'function') throw new TypeError('callback must be a function')\n  registrar.registerEvent(event, cb)\n}","typeGuard":"function isHandler (v: unknown): v is Function {\n  return typeof v === 'function'\n}","tryCatchPattern":null,"preventionTips":["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."],"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"}