{"record":{"id":"2b5b8fe6a78ceb76","repo":"usablica/intro.js","slug":"provided-callback-for-onbeforechange-was-not-a-fun","errorCode":null,"errorMessage":"Provided callback for onBeforeChange was not a function","messagePattern":"Provided callback for onBeforeChange was not a function","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packages/tour/tour.ts","lineNumber":520,"sourceCode":"    }\n\n    return this;\n  }\n\n  /**\n   * @deprecated onbeforechange is deprecated, please use onBeforeChange instead.\n   */\n  onbeforechange(callback: introBeforeChangeCallback) {\n    return this.onBeforeChange(callback);\n  }\n\n  /**\n   * Add a callback to be called before the tour changes steps\n   * @param {Function} callback callback function to be called\n   */\n  onBeforeChange(callback: introBeforeChangeCallback) {\n    if (!isFunction(callback)) {\n      throw new Error(\n        \"Provided callback for onBeforeChange was not a function\"\n      );\n    }\n\n    this.callbacks.beforeChange = callback;\n    return this;\n  }\n\n  /**\n   * @deprecated onchange is deprecated, please use onChange instead.\n   */\n  onchange(callback: introChangeCallback) {\n    this.onChange(callback);\n  }\n\n  /**\n   * Add a callback to be called when the tour changes steps\n   * @param {Function} callback callback function to be called","sourceCodeStart":502,"sourceCodeEnd":538,"githubUrl":"https://github.com/usablica/intro.js/blob/e5517e6a24e0530f87885af9fb2a69bafd1d4a6b/src/packages/tour/tour.ts#L502-L538","documentation":"Tour class onBeforeChange registers a callback executed before the tour switches steps, stored in this.callbacks.beforeChange. It throws this error when the argument fails the isFunction check, guaranteeing the internal invocation is always safe.","triggerScenarios":"introJs().onBeforeChange() or onBeforeChange(config.beforeChange) where the value is undefined, null, or non-function; note this variant's message has no trailing period.","commonSituations":"Framework integrations (React/Vue) passing state values that are undefined on first render; passing a hook/observer object instead of the callback; version migration where the callback name in a wrapper lib changed.","solutions":["Pass an explicit function: introJs().onBeforeChange(function(targetElement){ ... }).","Fix the source of the undefined value (config key typo, missing import, wrong prop name).","Defer registration until the handler exists (e.g., in a useEffect/mounted hook).","Check TypeScript optionality — supply a default no-op function for optional callbacks.","Wrap in try/catch during setup to fail fast with clearer context."],"exampleFix":"// before\nintroJs().onBeforeChange(props.beforeChange); // undefined on first render\n// after\nuseEffect(() => {\n  if (typeof props.beforeChange === 'function') {\n    introJs().onBeforeChange(props.beforeChange);\n  }\n}, []);","handlingStrategy":"type-guard","validationCode":"const safeBeforeChange = typeof cfg.beforeChange === 'function' ? cfg.beforeChange : () => {};\nintroJs().onBeforeChange(safeBeforeChange);","typeGuard":"const isFn = (v: unknown): v is (el: Element) => void => typeof v === 'function';","tryCatchPattern":"try {\n  tour.onBeforeChange(cb);\n} catch (e) {\n  if (e.message.startsWith('Provided callback for onBeforeChange')) {\n    tour.onBeforeChange(() => {});\n  } else { throw e; }\n}","preventionTips":["Register inside mount/useEffect where handler props are settled","Type optional callback props explicitly and default them","Don't pass framework refs/observers where plain functions are required","Unit-test tour setup with minimal config to catch bad wiring early"],"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"}