BookStackApp/BookStack · error · Error
Cannot call clear() on a frozen Lexical node map
Error message
Cannot call clear() on a frozen Lexical node map
What it means
Same frozen node-map dev guarantee as [147]: after pending state is frozen, calling .clear() on it throws 'Cannot call clear() on a frozen Lexical node map'. It exists to catch code clearing an editor state's node map that should be immutable once pending/committed.
Source
Thrown at resources/js/wysiwyg/lexical/core/LexicalUpdates.ts:469
activeEditorState = previousActiveEditorState;
isReadOnlyMode = previousReadOnlyMode;
activeEditor = previousActiveEditor;
}
}
function handleDEVOnlyPendingUpdateGuarantees(
pendingEditorState: EditorState,
): void {
// Given we can't Object.freeze the nodeMap as it's a Map,
// we instead replace its set, clear and delete methods.
const nodeMap = pendingEditorState._nodeMap;
nodeMap.set = () => {
throw new Error('Cannot call set() on a frozen Lexical node map');
};
nodeMap.clear = () => {
throw new Error('Cannot call clear() on a frozen Lexical node map');
};
nodeMap.delete = () => {
throw new Error('Cannot call delete() on a frozen Lexical node map');
};
}
export function $commitPendingUpdates(
editor: LexicalEditor,
recoveryEditorState?: EditorState,
): void {
const pendingEditorState = editor._pendingEditorState;
const rootElement = editor._rootElement;
const shouldSkipDOM = editor._headless || rootElement === null;
if (pendingEditorState === null) {
return;
}View on GitHub (pinned to 18f8469a1c)
Solutions
- Never clear an EditorState's _nodeMap; create a new state via parseEditorState/editor.setEditorState instead
- Refactor plugins to use public Lexical APIs for state changes
- Search codebase for direct _nodeMap usage and remove it
- If seen from a dependency, pin/update that dependency
Example fix
// before editorState._nodeMap.clear(); // after editor.setEditorState(editor.parseEditorState(serializedState));
Defensive patterns
Strategy: type-guard
Validate before calling
// To reset state, create a new one — never clear the map
if (needsReset) {
editor.setEditorState(editor.parseEditorState(serialized));
} Type guard
function canMutate(map: Map<string, unknown>): boolean {
try { map.set('__t', 0); map.delete('__t'); return true; } catch { return false; }
} Try / catch
try {
resetEditorState(editor);
} catch (e) {
if (/frozen Lexical node map/.test(e.message)) {
editor.setEditorState(editor.parseEditorState(emptyDoc));
}
} Prevention
- Replace 'clear the state' logic with setEditorState(new state)
- Avoid storing long-lived references to old EditorStates
- Audit code for direct _nodeMap access
- Treat editor states as read-only, always
When it happens
Trigger: Any dev-mode path calling nodeMap.clear() on a pendingEditorState._nodeMap after parseEditorState/$commitPendingUpdates froze it — internal misuse or plugin code holding the map reference.
Common situations: Custom code attempting to reset editor state by clearing its node map; plugins copying state via internal APIs; dev-only invariant failures.
Related errors
- Cannot call set() on a frozen Lexical node map
- Cannot call delete() on a frozen Lexical node map
- ${error.toString()} Parent: ${dom.tagName}, new child: {tag:
- ${method} is not supported in headless mode
- To use $generateHtmlFromNodes in headless mode please initia
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/3ff11e0c3328f6c0.
Report an issue: GitHub.