GrapesJS/grapesjs · error

Cannot add a layer model to another layer model

Error message

Cannot add a layer model to another layer model

What it means

LayerNode wraps either a Layers collection (a container of layers) or a single Layer model. addChildAt performs this.model.add(...), which is only valid on the Layers collection; if the node wraps a Layer, the library throws this error because a layer cannot contain other layers.

Source

Thrown at packages/core/src/utils/sorter/LayerNode.ts:48

  /**
   * Get the parent LayerNode of this component, or null if it has no parent.
   * @returns The parent LayerNode or null.
   */
  getParent(): LayerNode | null {
    const collection = this.model instanceof Layer ? this.model.collection : null;
    return collection ? new LayerNode(collection as Layers) : null;
  }

  /**
   * Add a child LayerNode at a particular index in the Layers model.
   * @param node - The LayerNode to add as a child.
   * @param index - The position to insert the child.
   * @returns The newly added LayerNode.
   * @throws Error if trying to add to a Layer (not a Layers).
   */
  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);

View on GitHub (pinned to 2bdeda85b8)

Solutions

  1. Only call addChildAt on nodes whose model is a Layers collection — check with `node.model instanceof Layers` first
  2. Insert into the root Layers collection or the parent collection of the target layer instead of the Layer itself
  3. If building drop logic, use canMove()/getChildren() (returns null for leaf Layers) to reject drops onto leaf nodes before calling addChildAt

Example fix

// before
node.addChildAt(child, 0); // node.model may be a Layer
// after
if (node.model instanceof Layers) {
  node.addChildAt(child, 0);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(node.model instanceof Layers)) {
  throw new Error('addChildAt 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.addChildAt(child, index);
} catch (e) {
  if (e.message.includes('Cannot add a layer model')) {
    // route insertion to the parent/root Layers collection instead
  }
}

Prevention

When it happens

Trigger: Calling addChildAt(node, index) on a LayerNode whose model is a Layer (a leaf) instead of a Layers collection — e.g. dropping a layer onto another layer rather than into the root Layers collection, or an off-by-one level error when walking the layer tree.

Common situations: Custom drag-and-drop layer management built on the internal sorter utilities; nesting layers by mistake when the style manager's layer tree is only two levels (Layers -> Layer); tests or scripts that fetch children of a Layer (getChildren returns null) and then assume an insertable parent.

Related errors


AI-assisted analysis of GrapesJS/grapesjs@2bdeda85b8 (2026-08-30). Data as JSON: /api/errors/bfcfd4b64bc68794. Report an issue: GitHub.