ankane/pghero · error · Error

noUiSlider: 'cssClasses' must be an object.

Error message

noUiSlider: 'cssClasses' must be an object.

What it means

noUiSlider (vendored at app/assets/javascripts/pghero/nouislider.js) validates every option passed to create(). testCssClasses requires the cssClasses option to be a plain object mapping internal class keys (target, origin, handle, ...) to CSS class names. Anything else - a string, a number, null - throws this Error during initialization, before the slider is built.

Source

Thrown at app/assets/javascripts/pghero/nouislider.js:803

    function testKeyboardSupport(parsed, entry) {
        if (typeof entry !== "boolean") {
            throw new Error("noUiSlider: 'keyboardSupport' option must be a boolean.");
        }
        parsed.keyboardSupport = entry;
    }
    function testDocumentElement(parsed, entry) {
        // This is an advanced option. Passed values are used without validation.
        parsed.documentElement = entry;
    }
    function testCssPrefix(parsed, entry) {
        if (typeof entry !== "string" && entry !== false) {
            throw new Error("noUiSlider: 'cssPrefix' must be a string or `false`.");
        }
        parsed.cssPrefix = entry;
    }
    function testCssClasses(parsed, entry) {
        if (typeof entry !== "object") {
            throw new Error("noUiSlider: 'cssClasses' must be an object.");
        }
        if (typeof parsed.cssPrefix === "string") {
            parsed.cssClasses = {};
            Object.keys(entry).forEach(function (key) {
                parsed.cssClasses[key] = parsed.cssPrefix + entry[key];
            });
        }
        else {
            parsed.cssClasses = entry;
        }
    }
    // Test all developer settings and parse to assumption-safe values.
    function testOptions(options) {
        // To prove a fix for #537, freeze options here.
        // If the object is modified, an error will be thrown.
        // Object.freeze(options);
        var parsed = {
            margin: null,

View on GitHub (pinned to 7edb57986f)

Solutions

  1. Pass an object: cssClasses: {target: "my-target", origin: "my-origin"} using the documented internal key names
  2. If you only want a prefix on all generated classes, use cssPrefix: "my-" (string) instead of cssClasses
  3. For a global change across all sliders, modify the exported nouislider.cssClasses default instead of per-create options

Example fix

// before
noUiSlider.create(el, { cssClasses: "slider" });

// after - object mapping internal keys to class names
noUiSlider.create(el, { cssClasses: { target: "slider" } });
Defensive patterns

Strategy: type-guard

Validate before calling

const cssClasses = options.cssClasses;
if (cssClasses !== undefined && (typeof cssClasses !== "object" || cssClasses === null)) {
  console.warn("cssClasses must be an object; ignoring");
  delete options.cssClasses;
}
noUiSlider.create(el, options);

Type guard

function isValidCssClasses(v) {
  return v === undefined || (typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every(x => typeof x === "string"));
}

Prevention

When it happens

Trigger: Calling noUiSlider.create(el, {cssClasses: "custom"}) or {cssClasses: null}. Note that PgHero itself never customizes cssClasses, so this only fires in application code that extends the vendored slider's options, or when options objects are merged from an external source that supplies a non-object cssClasses value.

Common situations: Developers assume cssClasses takes a string like cssPrefix does; option objects built dynamically (e.g. JSON config) where cssClasses is a string or missing-typed; copying examples from a different noUiSlider major version whose option shapes changed.

Related errors


AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21). Data as JSON: /api/errors/81f29a2e9f97e1c1. Report an issue: GitHub.