toeverything/AFFiNE · error · Error

Cannot move a node to its descendant

Error message

Cannot move a node to its descendant

What it means

A cycle guard in moveNode: after ruling out self-parenting, isAncestor(parentId, nodeId) walks the ancestor chain and this fires when the target parent is a descendant of the node being moved. It prevents re-parenting a folder into its own subtree, which would create a cycle and orphan the branch.

Source

Thrown at packages/frontend/core/src/modules/organize/stores/folder.ts:137

    const link = this.dbService.db.folders.get(linkId);
    if (link === null || link.type === 'folder') {
      throw new Error('Link not found');
    }
    this.dbService.db.folders.delete(linkId);
  }

  moveNode(nodeId: string, parentId: string | null, index: string) {
    const node = this.dbService.db.folders.get(nodeId);
    if (node === null) {
      throw new Error('Node not found');
    }

    if (parentId) {
      if (nodeId === parentId) {
        throw new Error('Cannot move a node to itself');
      }
      if (this.isAncestor(parentId, nodeId)) {
        throw new Error('Cannot move a node to its descendant');
      }
      const parent = this.dbService.db.folders.get(parentId);
      if (parent === null || parent.type !== 'folder') {
        throw new Error('Parent folder not found');
      }
    } else {
      if (node.type !== 'folder') {
        throw new Error('Root node can only have folders');
      }
    }
    this.dbService.db.folders.update(nodeId, {
      parentId,
      index,
    });
  }
}

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Choose a destination that is not inside the moved node.
  2. Check descendants before moving.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown by moveNode when the target parentId is a descendant of the node being moved (isAncestor check), which would create a cycle in the folder tree.

Common situations: A user tries to move a folder into one of its own subfolders. Choose a destination outside the folder's own subtree.


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/2eae43b563a25869. Report an issue: GitHub.