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

  1. Pass an actual function: introJs().onHintsAdded(function(hints, hintObjects){ ... }).
  2. Log the value with console.log(typeof myCb) and fix the variable that is undefined or not a function.
  3. 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.
  4. Update code that used the deprecated lowercase alias onhintsadded if it passes a non-function.
  5. 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

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


AI-assisted analysis of usablica/intro.js@e5517e6a24 (2026-08-31). Data as JSON: /api/errors/671bc26863d7e3d6. Report an issue: GitHub.