GrapesJS/grapesjs · warning
Selector Manager not found
Error message
Selector Manager not found
What it means
When loading CSS rules via the CSS composer (addCollection/addRules), each rule's selectors must be resolved against the editor's Selector Manager (em?.Selectors). If the EditorModel (em) is missing or has no Selectors module, the library cannot create/attach selectors for the rule and only logs this warning instead of throwing, so the rule is added without proper selector handling.
Source
Thrown at packages/core/src/css_composer/index.ts:323
*/
addCollection(data: string | CssRuleJSON[], opts: AddCollectionOptions = {}, props = {}) {
const { em } = this;
const result: CssRule[] = [];
const parsedImportOpts: AddCollectionOptions = { ...opts, parsedImportSource: 'css' as const };
if (isString(data)) {
data = em.Parser.parseCss(data);
opts = parsedImportOpts;
}
const d = data instanceof Array ? data : [data];
for (var i = 0, l = d.length; i < l; i++) {
const rule = (d[i] || {}) as CssRuleJSON;
if (!rule.selectors) continue;
const sm = em?.Selectors;
if (!sm) console.warn('Selector Manager not found');
const sl = rule.selectors;
const sels = sl instanceof Array ? sl : [sl];
const newSels = [];
for (let j = 0, le = sels.length; j < le; j++) {
// @ts-ignore
const selec = sm.add(sels[j]);
newSels.push(selec);
}
const modelExists = this.get(newSels, rule.state, rule.mediaText, rule);
const model = this.add(newSels, rule.state, rule.mediaText, rule, opts);
const updateStyle = !modelExists || !opts.avoidUpdateStyle;
const style = rule.style || {};
isObject(props) && model.set(props, opts);
if (updateStyle) {View on GitHub (pinned to 2bdeda85b8)
Solutions
- Wait for editor initialization (editor.on('load') / await editor.ready) before calling addCollection or addRules
- Pass the editor instance's em correctly — ensure addRules is called on editor.Css, not on a detached CssComposer constructed without an editor model
- Check that em?.Selectors exists at runtime; if null, re-initialize the editor rather than continuing
- Upgrade to a version where CssComposer is always constructed with the editor model (em) reference
Example fix
// before
editor.Css.addCollection(rules); // may run before Selectors is ready
// after
editor.on('load', () => editor.Css.addCollection(rules)); Defensive patterns
Strategy: validation
Validate before calling
if (!editor || !editor.em || !editor.em.Selectors) {
throw new Error('Editor Selector Manager not ready; cannot load CSS rules yet');
}
editor.Css.addCollection(rules); Type guard
function isSelectorManagerReady(ed: any): ed is { em: { Selectors: object } } {
return !!ed && !!ed.em && !!ed.em.Selectors;
} Prevention
- Load CSS rules only after the editor 'load'/'ready' event
- Keep a single reference to the editor instance; never reuse destroyed editors
- Assert em.Selectors exists in dev builds before calling Css APIs
When it happens
Trigger: Calling editor.Css.addCollection(rules) or addRules(rules) before the editor has fully initialized its module manager, or on a partially constructed / headless editor instance where em is undefined or em.Selectors was not created.
Common situations: Invoking CSS-loading APIs immediately after editor construction but before the 'load'/'ready' event; destroying the editor and reusing stale references; custom builds where the Selector Manager module was removed or initialization failed silently.
Related errors
- Target option is required
- Cannot modify immutable record
- Cannot remove immutable record
- 'container' is required
- Parser code "${parserCode}" not found
AI-assisted analysis of GrapesJS/grapesjs@2bdeda85b8 (2026-08-30).
Data as JSON: /api/errors/9ff6c9ee33650133.
Report an issue: GitHub.