BookStackApp/BookStack · error · Error
Attempted to get use node without it being set
Error message
Attempted to get use node without it being set
What it means
Decorator UI subclasses wrap a LexicalNode, which is assigned via setNode(). The protected getNode() accessor throws if the node was never set, preventing decorators from operating on an undefined node. This is an internal lifecycle contract: construct -> setNode -> render/update.
Source
Thrown at resources/js/wysiwyg/ui/framework/decorator.ts:22
export interface EditorDecoratorAdapter {
type: string;
getNode(): LexicalNode;
}
export abstract class EditorDecorator {
protected node: LexicalNode | null = null;
protected context: EditorUiContext;
private onDestroyCallbacks: (() => void)[] = [];
constructor(context: EditorUiContext) {
this.context = context;
}
protected getNode(): LexicalNode {
if (!this.node) {
throw new Error('Attempted to get use node without it being set');
}
return this.node;
}
setNode(node: LexicalNode) {
this.node = node;
}
/**
* Register a callback to be ran on destroy of this decorator's node.
*/
protected onDestroy(callback: () => void) {
this.onDestroyCallbacks.push(callback);
}
/**
* Render the decorator.View on GitHub (pinned to 18f8469a1c)
Solutions
- Always call setNode(node) on a decorator immediately after construction, before any other interaction.
- In custom decorator code, use setNode() or the framework's creation path instead of relying on a default node value.
- Check that the Lexical transform/import logic creating the decorator completes node assignment before rendering.
- Guard custom code against using the decorator during its setup phase.
Example fix
// before const decorator = new MyDecorator(context); decorator.update(); // getNode() throws // after const decorator = new MyDecorator(context); decorator.setNode(theLexicalNode); decorator.update(); // safe
Defensive patterns
Strategy: type-guard
Validate before calling
// Only interact with a decorator once its node has been assigned
function decoratorHasNode(d: EditorUiDecorator): boolean {
return (d as unknown as { node?: LexicalNode | null }).node != null;
}
if (decoratorHasNode(decorator)) {
decorator.update();
} Type guard
function hasNode(d: EditorUiDecorator): d is EditorUiDecorator & { node: LexicalNode } {
return (d as unknown as { node?: LexicalNode | null }).node != null;
}
if (hasNode(decorator)) { decorator.update(); } Try / catch
try {
decorator.update();
} catch (e) {
if (e instanceof Error && e.message.includes('use node without it being set')) {
decorator.setNode(someLexicalNode);
decorator.update();
} else { throw e; }
} Prevention
- Call setNode() immediately after constructing a decorator, before any rendering/update call.
- Never instantiate decorators manually outside the framework's node-creation path.
- In custom subclasses, keep the construct -> setNode -> use order intact.
- Add a test asserting every decorator creation path assigns a node before first use.
When it happens
Trigger: Calling a method on an EditorUiDecorator subclass that internally calls getNode() before setNode(node) was invoked — e.g. creating a decorator instance manually and using it before assignment, or the framework invoking decorator hooks on an instance whose node assignment was skipped.
Common situations: Custom decorator subclasses that break the lifecycle and forget to call setNode; instantiating a decorator by hand in tests or custom UI code without wiring it to a node; a Lexical transform that constructs the decorator but errors before node assignment.
Related errors
- ${error.toString()} Parent: ${dom.tagName}, new child: {tag:
- Cannot call set() on a frozen Lexical node map
- Cannot call clear() on a frozen Lexical node map
- Cannot call delete() on a frozen Lexical node map
- ${method} is not supported in headless mode
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/cd998bb80558701b.
Report an issue: GitHub.