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 updatedView on GitHub (pinned to 1d090e0b5f)
Solutions
- Run plotly.js only in a real browser environment; in tests, polyfill CSSOM or mock insertRule in your DOM shim.
- Check for polyfills that replace document.head or style elements; remove or fix them.
- Confirm the target browser supports CSSStyleSheet.insertRule (all modern ones do) — drop legacy webview targets if they don't.
- If the warning appears in SSR output, guard plotly.js behind client-only imports (dynamic import in useEffect / client-only component).
- 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
- Run plotly.js only in real browsers; lazy-load it client-side in SSR apps.
- Polyfill or stub CSSOM in jsdom-based test suites.
- Remove polyfills that replace document.head or style elements.
- Drop legacy webviews lacking insertRule/addRule.
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.