plotly/plotly.js · warning

addStyleRule failed

Error message

addStyleRule failed

What it means

After obtaining a stylesheet object, addRelatedStyleRule inserts rules with insertRule, falling back to the legacy addRule. If a sheet exists but supports neither method (or the call context is unexpected), the library warns 'addStyleRule failed' and the CSS is not applied.

Source

Thrown at src/lib/dom.js:82

        // Do not proceed if user disable inline styles explicitly...
        return;
    }
    if(!style) {
        style = document.createElement('style');
        style.setAttribute('id', id);
        // WebKit hack :(
        style.appendChild(document.createTextNode(''));
        document.head.appendChild(style);
    }
    var styleSheet = style.sheet;

    if(!styleSheet) {
        loggers.warn('Cannot addRelatedStyleRule, probably due to strict CSP...');
    } else if(styleSheet.insertRule) {
        styleSheet.insertRule(selector + '{' + styleString + '}', 0);
    } else if(styleSheet.addRule) {
        styleSheet.addRule(selector, styleString, 0);
    } else loggers.warn('addStyleRule failed');
}

/**
 * to remove from the page a stylesheet identified by a given uid
 */
function deleteRelatedStyleRule(uid) {
    var id = 'plotly.js-style-' + uid;
    var style = document.getElementById(id);
    if(style) removeElement(style);
}

/**
 * Setup event listeners on button elements to emulate the ':hover' state without using inline styles,
 * which is not allowed with strict CSP.  This supports modebar buttons set with the 'active' class,
 * in which case, the active style remains even when it's no longer hovered.
 * @param {string} selector selector for button elements to be styled when hovered
 * @param {string} activeSelector selector used to determine if selected element is active
 * @param {string} childSelector the child element on which the styling needs to be updated

View on GitHub (pinned to 1d090e0b5f)

Solutions

  1. Run plotly.js only in a real browser environment; in tests, polyfill CSSOM or mock insertRule in your DOM shim.
  2. Check for polyfills that replace document.head or style elements; remove or fix them.
  3. Confirm the target browser supports CSSStyleSheet.insertRule (all modern ones do) — drop legacy webview targets if they don't.
  4. If the warning appears in SSR output, guard plotly.js behind client-only imports (dynamic import in useEffect / client-only component).
  5. File an upstream issue with environment details if triggered in a supported browser.

Example fix

// before (SSR / jsdom)
import Plotly from 'plotly.js-dist'; // runs during SSR, no CSSOM
// after
useEffect(() => {
  import('plotly.js-dist').then(Plotly => Plotly.newPlot(gd, data, layout));
}, []);
Defensive patterns

Strategy: fallback

Validate before calling

function cssomReady() {
  const s = document.createElement('style');
  document.head.appendChild(s);
  const sheet = s.sheet;
  const ok = !!sheet && (typeof sheet.insertRule === 'function' || typeof sheet.addRule === 'function');
  s.remove();
  return ok;
}

Try / catch

if (!cssomReady()) {
  console.warn('CSSOM unavailable; skipping dynamic plotly styles');
  return fallbackStaticStyles();
}

Prevention

When it happens

Trigger: A browser/environment where style.sheet exists but lacks both insertRule and addRule — e.g. non-standard DOM implementations, jsdom/SSR shims, or a stylesheet in a state that exposes no rule-insertion API.

Common situations: Server-side rendering or running plotly.js in jsdom-based tests where CSSOM is partially implemented; exotic embedded browsers or webviews with incomplete CSSOM; monkey-patched document/head in an app's polyfills.

Related errors


AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02). Data as JSON: /api/errors/c901c7ee298099da. Report an issue: GitHub.