usablica/intro.js · error
Provided callback for onBeforeChange was not a function
Error message
Provided callback for onBeforeChange was not a function
What it means
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.
Source
Thrown at src/packages/tour/tour.ts:520
}
return this;
}
/**
* @deprecated onbeforechange is deprecated, please use onBeforeChange instead.
*/
onbeforechange(callback: introBeforeChangeCallback) {
return this.onBeforeChange(callback);
}
/**
* Add a callback to be called before the tour changes steps
* @param {Function} callback callback function to be called
*/
onBeforeChange(callback: introBeforeChangeCallback) {
if (!isFunction(callback)) {
throw new Error(
"Provided callback for onBeforeChange was not a function"
);
}
this.callbacks.beforeChange = callback;
return this;
}
/**
* @deprecated onchange is deprecated, please use onChange instead.
*/
onchange(callback: introChangeCallback) {
this.onChange(callback);
}
/**
* Add a callback to be called when the tour changes steps
* @param {Function} callback callback function to be calledView on GitHub (pinned to e5517e6a24)
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.
Example fix
// before
introJs().onBeforeChange(props.beforeChange); // undefined on first render
// after
useEffect(() => {
if (typeof props.beforeChange === 'function') {
introJs().onBeforeChange(props.beforeChange);
}
}, []); Defensive patterns
Strategy: type-guard
Validate before calling
const safeBeforeChange = typeof cfg.beforeChange === 'function' ? cfg.beforeChange : () => {};
introJs().onBeforeChange(safeBeforeChange); Type guard
const isFn = (v: unknown): v is (el: Element) => void => typeof v === 'function';
Try / catch
try {
tour.onBeforeChange(cb);
} catch (e) {
if (e.message.startsWith('Provided callback for onBeforeChange')) {
tour.onBeforeChange(() => {});
} else { throw e; }
} Prevention
- 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
When it happens
Trigger: introJs().onBeforeChange() or onBeforeChange(config.beforeChange) where the value is undefined, null, or non-function; note this variant's message has no trailing period.
Common situations: 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.
Related errors
- Provided callback for onhintsadded was not a function.
- Provided callback for onhintclick was not a function.
- Provided callback for onhintclose was not a function.
- Provided callback for onChange was not a function.
- Provided callback for onAfterChange was not a function
AI-assisted analysis of usablica/intro.js@e5517e6a24 (2026-08-31).
Data as JSON: /api/errors/2b5b8fe6a78ceb76.
Report an issue: GitHub.