Skip to content

Removing a ComponentNode cascades to remove orphaned instances, corrupting page.children snapshots #352

@kevinj-rsp

Description

@kevinj-rsp

Summary

When you remove a ComponentNode from a page, Figma silently also removes any orphaned instances of that component on the same page. If you spread page.children into an array first and then loop over it to remove nodes, the cascade removal makes some references stale, causing subsequent .remove() calls to throw:

in remove: The node with id "X:Y" does not exist

Reproduction

// Page contains: compFrame (holds ComponentSet), plus some orphaned instances
// of those components left over from a previous failed build.

await page.loadAsync();
const children = [...page.children]; // snapshot includes both compFrame + orphaned instances

for (const child of children) {
  child.remove();
  // Removing compFrame removes the ComponentSet and its variants.
  // Figma also silently removes the orphaned instances of those variants.
  // Later iterations try to remove those instances — they no longer exist → throws.
}

Expected behavior

Either:

  1. Removing a component should not cascade-remove instances (instances should become detached/broken, as they do in the UI), or
  2. The cascade behavior should be documented, so developers know not to snapshot page.children before a remove loop.

Workaround

Drain page.children live instead of snapshotting:

while (page.children.length > 0) page.children[0].remove();

This always reads the fresh live list, so cascade removals are naturally absorbed.

Context

Hit this when building a plugin that clears and regenerates pages on each run (getOrResetPage). A previous build had failed mid-way and left orphaned button instances on the page. On the next run, clearing the page triggered the cascade.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions