{"record":{"id":"fd18e2b20fe27abc","repo":"GrapesJS/grapesjs","slug":"cannot-remove-a-layer-model-from-another-layer-mod","errorCode":null,"errorMessage":"Cannot remove a layer model from another layer model","messagePattern":"Cannot remove a layer model from another layer model","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/utils/sorter/LayerNode.ts","lineNumber":63,"sourceCode":"   */\n  addChildAt(node: LayerNode, index: number) {\n    if (this.model instanceof Layer) {\n      throw Error('Cannot add a layer model to another layer model');\n    }\n\n    const newModel = this.model.add(node.model, { at: index });\n    return new LayerNode(newModel);\n  }\n\n  /**\n   * Remove a child LayerNode at a specified index in the Layers model.\n   * @param index - The index of the child to remove.\n   * @returns The removed LayerNode.\n   * @throws Error if trying to remove from a Layer (not a Layers).\n   */\n  removeChildAt(index: number) {\n    if (this.model instanceof Layer) {\n      throw Error('Cannot remove a layer model from another layer model');\n    }\n\n    const child = this.model.at(index);\n    if (child) {\n      this.model.remove(child);\n    }\n  }\n\n  /**\n   * Get the index of a child LayerNode in the current Layers model.\n   * @param node - The child LayerNode to find.\n   * @returns The index of the child, or -1 if not found.\n   */\n  indexOfChild(node: LayerNode): number {\n    if (!(node.model instanceof Layer) || !(this.model instanceof Layers)) {\n      return -1;\n    }\n    return this.model.indexOf(node.model);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/GrapesJS/grapesjs/blob/2bdeda85b82b8b9ceae42fd6558cbbcae5ec2d21/packages/core/src/utils/sorter/LayerNode.ts#L45-L81","documentation":"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.","triggerScenarios":"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()).","commonSituations":"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.","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"],"exampleFix":"// before\nselectedNode.removeChildAt(index); // selectedNode is a leaf Layer\n// after\nconst parent = selectedNode.getParent();\nif (parent) {\n  parent.removeChildAt(parent.indexOfChild(selectedNode));\n}","handlingStrategy":"type-guard","validationCode":"if (!(node.model instanceof Layers)) {\n  throw new Error('removeChildAt requires a Layers collection node');\n}","typeGuard":"function isLayersNode(n: LayerNode): n is LayerNode & { model: Layers } {\n  return n.model instanceof Layers;\n}","tryCatchPattern":"try {\n  node.removeChildAt(index);\n} catch (e) {\n  if (e.message.includes('Cannot remove a layer model')) {\n    // retry on the parent collection instead\n  }\n}","preventionTips":["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"],"tags":["tree","layers","sorter","typescript"],"backgroundTag":"invalid-tree-parent-node","analyzedSha":"2bdeda85b82b8b9ceae42fd6558cbbcae5ec2d21","analyzedAt":"2026-08-30T11:47:52.267Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}