usablica/intro.js · error
Provided callback for onhintsadded was not a function.
Error message
Provided callback for onhintsadded was not a function.
What it means
intro.js's Hint class method onHintsAdded registers a callback invoked after hints are added. Before storing it in this.callbacks.hintsAdded, it validates the argument with isFunction and throws this error when the argument is not a function. This is a defensive guard so later invocation sites never crash calling a non-function.
Source
Thrown at src/packages/hint/hint.ts:395
}
/**
* Clone the Hint instance
*/
clone(): ThisType<this> {
return new Hint(this._targetElement, this._options);
}
/**
* Returns true if the Hint is active
*/
isActive(): boolean {
return this.getOption("isActive");
}
onHintsAdded(providedCallback: hintsAddedCallback) {
if (!isFunction(providedCallback)) {
throw new Error("Provided callback for onhintsadded was not a function.");
}
this.callbacks.hintsAdded = providedCallback;
return this;
}
/**
* @deprecated onhintsadded is deprecated, please use onHintsAdded instead
* @param providedCallback callback function
*/
onhintsadded(providedCallback: hintsAddedCallback) {
this.onHintsAdded(providedCallback);
}
/**
* Callback for when hint items are clicked
* @param providedCallback callback function
*/View on GitHub (pinned to e5517e6a24)
Solutions
- Pass an actual function: introJs().onHintsAdded(function(hints, hintObjects){ ... }).
- Log the value with console.log(typeof myCb) and fix the variable that is undefined or not a function.
- Check option-object style config (hints-added / onHintsAdded key) and ensure the value is a function, not its name or result of calling the function.
- Update code that used the deprecated lowercase alias onhintsadded if it passes a non-function.
- Wrap the call in a try/catch to surface the misconfiguration early.
Example fix
// before
const myCb = config.hintsCb; // undefined (typo: config.hintsCallback)
introJs().onHintsAdded(myCb);
// after
introJs().onHintsAdded(function(hints) {
console.log('hints added', hints);
}); Defensive patterns
Strategy: validation
Validate before calling
if (typeof cb !== 'function') { throw new TypeError('onHintsAdded expects a function, got ' + typeof cb); }
introJs().onHintsAdded(cb); Type guard
function isCallable(v) { return typeof v === 'function'; } Try / catch
try {
introJs().onHintsAdded(cb);
} catch (e) {
if (e.message.includes('onhintsadded was not a function')) {
console.error('Bad hints-added callback:', cb);
} else { throw e; }
} Prevention
- Always pass function references, not names or results of calls
- TypeScript: type callbacks as ((hints: HTMLElement[]) => void) | undefined and check before use
- Default optional callbacks to a no-op function at config load time
- Register callbacks in initialization code after all handlers are defined
- Avoid the deprecated lowercase aliases; use camelCase setters
When it happens
Trigger: Calling introJs().addHints() config path or hintObject registration where onHintsAdded(...) is passed undefined, null, a string, or a wrongly-named variable instead of a function, e.g. introJs().onHintsAdded().
Common situations: Typo'd callback names loaded as undefined; passing an object like {cb: fn} instead of the function itself; migrating from older intro.js versions where the setter silently accepted anything; calling before the callback variable is assigned (async load order).
Related errors
- Provided callback for onhintclick was not a function.
- Provided callback for onhintclose was not a function.
- Provided callback for onBeforeChange 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/671bc26863d7e3d6.
Report an issue: GitHub.