{"record":{"id":"0e426182d9801c43","repo":"usablica/intro.js","slug":"provided-callback-for-onstart-was-not-a-function","errorCode":null,"errorMessage":"Provided callback for onstart was not a function.","messagePattern":"Provided callback for onstart was not a function\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packages/tour/tour.ts","lineNumber":602,"sourceCode":"\n    this.callbacks.complete = callback;\n    return this;\n  }\n\n  /**\n   * @deprecated onstart is deprecated, please use onStart instead.\n   */\n  onstart(callback: introStartCallback) {\n    return this.onStart(callback);\n  }\n\n  /**\n   * Add a callback to be called when the tour is started\n   * @param {Function} callback callback function to be called\n   */\n  onStart(callback: introStartCallback) {\n    if (!isFunction(callback)) {\n      throw new Error(\"Provided callback for onstart was not a function.\");\n    }\n\n    this.callbacks.start = callback;\n    return this;\n  }\n\n  /**\n   * @deprecated onexit is deprecated, please use onExit instead.\n   */\n  onexit(callback: introExitCallback) {\n    return this.onExit(callback);\n  }\n\n  /**\n   * Add a callback to be called when the tour is exited\n   * @param {Function} callback callback function to be called\n   */\n  onExit(callback: introExitCallback) {","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/usablica/intro.js/blob/e5517e6a24e0530f87885af9fb2a69bafd1d4a6b/src/packages/tour/tour.ts#L584-L620","documentation":"Tour class onStart registers the callback fired when the tour starts, stored in this.callbacks.start. It validates the argument with isFunction and throws this error otherwise, preventing a TypeError at tour start time.","triggerScenarios":"introJs().onStart() or onStart(someNonFunction) — undefined from an unassigned variable, null, or an event-emitter object passed by mistake.","commonSituations":"Setting up tours from JSON-driven config where callbacks must be mapped by name in JS; hot-reload environments losing handler assignments; wrong method chaining order leaving a helper undefined.","solutions":["Pass an actual function: introJs().onStart(function(element){ ... }).","Log/inspect the argument type and fix the variable producing a non-function.","Wire config-name strings to functions explicitly: const cbs = {start: fn, ...}.","Use a fallback no-op when the callback is optional.","Catch the throw during setup to surface misconfiguration early."],"exampleFix":"// before\nconst cbs = { onStart: 'startTour' };\nintroJs().onStart(cbs.onStart); // string\n// after\nintroJs().onStart(cbs.startHandler); // function reference","handlingStrategy":"validation","validationCode":"const startCb = cbs.onStart;\nif (typeof startCb !== 'function') { throw new TypeError('onStart callback must be a function'); }\nintroJs().onStart(startCb);","typeGuard":"type IntroCb = (el?: Element) => void;\nconst isIntroCb = (v: unknown): v is IntroCb => typeof v === 'function';","tryCatchPattern":"try {\n  tour.onStart(cb);\n} catch (e) {\n  if (e.message.includes('onstart was not a function')) {\n    tour.onStart(() => {});\n  } else { throw e; }\n}","preventionTips":["Map string config names to functions explicitly in one place","Never pass event-emitter or observer objects as callbacks","Guard hot-reload code that reassigns handler variables","Default optional callbacks to no-ops"],"tags":["callbacks","type-validation","api-misuse"],"backgroundTag":"callback-not-a-function","analyzedSha":"e5517e6a24e0530f87885af9fb2a69bafd1d4a6b","analyzedAt":"2026-08-31T22:12:26.007Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}