GrapesJS/grapesjs · error
Cannot remove a layer model from another layer model
Error message
Cannot remove a layer model from another layer model
What it means
LayerNode.removeChildAt removes the child at an index via this.model.at(index)/remove(...), which only works when the wrapped model is a Layers collection. If the node wraps a single Layer, the library throws this error because a Layer is a leaf, not a container.
Source
Thrown at packages/core/src/utils/sorter/LayerNode.ts:63
*/
addChildAt(node: LayerNode, index: number) {
if (this.model instanceof Layer) {
throw Error('Cannot add a layer model to another layer model');
}
const newModel = this.model.add(node.model, { at: index });
return new LayerNode(newModel);
}
/**
* Remove a child LayerNode at a specified index in the Layers model.
* @param index - The index of the child to remove.
* @returns The removed LayerNode.
* @throws Error if trying to remove from a Layer (not a Layers).
*/
removeChildAt(index: number) {
if (this.model instanceof Layer) {
throw Error('Cannot remove a layer model from another layer model');
}
const child = this.model.at(index);
if (child) {
this.model.remove(child);
}
}
/**
* Get the index of a child LayerNode in the current Layers model.
* @param node - The child LayerNode to find.
* @returns The index of the child, or -1 if not found.
*/
indexOfChild(node: LayerNode): number {
if (!(node.model instanceof Layer) || !(this.model instanceof Layers)) {
return -1;
}
return this.model.indexOf(node.model);View on GitHub (pinned to 2bdeda85b8)
Solutions
- Call removeChildAt on the node's parent (node.getParent()) rather than on the Layer node itself
- Guard with `node.model instanceof Layers` before calling removeChildAt
- Use the model API directly on the collection: `layersCollection.remove(layer)` when you already hold both references
Example fix
// before
selectedNode.removeChildAt(index); // selectedNode is a leaf Layer
// after
const parent = selectedNode.getParent();
if (parent) {
parent.removeChildAt(parent.indexOfChild(selectedNode));
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(node.model instanceof Layers)) {
throw new Error('removeChildAt requires a Layers collection node');
} Type guard
function isLayersNode(n: LayerNode): n is LayerNode & { model: Layers } {
return n.model instanceof Layers;
} Try / catch
try {
node.removeChildAt(index);
} catch (e) {
if (e.message.includes('Cannot remove a layer model')) {
// retry on the parent collection instead
}
} Prevention
- Call removeChildAt on getParent(), not on the leaf Layer node
- Guard with node.model instanceof Layers before removal
- Use indexOfChild() on the parent to compute the correct index
- Remember Layer nodes are leaves — only Layers collections support child removal
When it happens
Trigger: Calling removeChildAt(index) on a LayerNode whose model is a Layer instead of a Layers collection — e.g. deleting a sub-layer by resolving the wrong tree level, or calling removeChildAt on the leaf node itself rather than its parent (getParent()).
Common situations: Custom layer-management UIs implementing delete on the selected node instead of its parent collection; recursive tree-removal code that assumes uniform nesting depth; code ported from ComponentNode sorting where children exist at more levels.
Related errors
AI-assisted analysis of GrapesJS/grapesjs@2bdeda85b8 (2026-08-30).
Data as JSON: /api/errors/fd18e2b20fe27abc.
Report an issue: GitHub.