usablica/intro.js · error
Provided callback for oncomplete was not a function.
Error message
Provided callback for oncomplete was not a function.
What it means
Tour class onComplete registers the callback fired when the tour finishes, stored in this.callbacks.complete. It throws when isFunction(callback) is false, keeping later invocation safe. Note the error message uses the lowercase alias 'oncomplete'.
Source
Thrown at src/packages/tour/tour.ts:582
this.callbacks.afterChange = callback;
return this;
}
/**
* @deprecated oncomplete is deprecated, please use onComplete instead.
*/
oncomplete(callback: introCompleteCallback) {
return this.onComplete(callback);
}
/**
* Add a callback to be called when the tour is completed
* @param {Function} callback callback function to be called
*/
onComplete(callback: introCompleteCallback) {
if (!isFunction(callback)) {
throw new Error("Provided callback for oncomplete was not a function.");
}
this.callbacks.complete = callback;
return this;
}
/**
* @deprecated onstart is deprecated, please use onStart instead.
*/
onstart(callback: introStartCallback) {
return this.onStart(callback);
}
/**
* Add a callback to be called when the tour is started
* @param {Function} callback callback function to be called
*/
onStart(callback: introStartCallback) {View on GitHub (pinned to e5517e6a24)
Solutions
- Pass a function: introJs().onComplete(function(){ ... }).
- Ensure the deprecated oncomplete alias (if used) also receives a function, or migrate to onComplete.
- Fix undefined handler variables (typos, load order, missing imports).
- Default optional callbacks: introJs().onComplete(cfg.done || (() => {})).
- Wrap setup in try/catch to identify the bad registration.
Example fix
// before introJs().oncomplete(doneUrl); // string, not function // after introJs().onComplete(() => window.location.assign(doneUrl));
Defensive patterns
Strategy: validation
Validate before calling
if (typeof doneCb === 'function') { introJs().onComplete(doneCb); } else { introJs().onComplete(() => {}); } Type guard
function isFn(v: unknown): v is () => void { return typeof v === 'function'; } Try / catch
try {
intro().onComplete(cb);
} catch (e) {
if (/oncomplete was not a function/.test(e.message)) {
intro().onComplete(() => {}); // swallow with fallback
} else { throw e; }
} Prevention
- Use the modern camelCase onComplete API
- Do not pass URLs/strings expecting the library to navigate; wrap in a function
- Confirm callback variables are assigned at registration time
- Keep callback wiring adjacent to introJs() creation
When it happens
Trigger: introJs().onComplete() with a non-function argument, or via the deprecated lowercase alias oncomplete passed a non-function.
Common situations: Migrating from intro.js's old lowercase alias API and passing the wrong thing; passing a routing navigation object; callback defined conditionally in code that skips its definition.
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 onBeforeChange was not a function
- Provided callback for onChange was not a function.
AI-assisted analysis of usablica/intro.js@e5517e6a24 (2026-08-31).
Data as JSON: /api/errors/07255dc6d147b7ab.
Report an issue: GitHub.