Comfy-Org / Comfy-Org/ComfyUI_frontend

layoutStore spatial index silently drops nodes outside ±10000

Open
#15,254 0 comments 0 reactions 0 assignees View on GitHub
Potential Bug verified bug
Dominant language
TypeScript
Stars
2k
Forks
704
Avg merge
1d 8h
Merged PRs (30d)
512

Description

## Summary
`layoutStore`'s node spatial index cannot hold a node whose bounds fall outside a fixed ±10000 box, and drops it without any signal. Real workflows outgrow that box, so `queryNodesInBounds` and every hit-test built on it return incomplete results.

## Detail
- `layoutStore` constructs `SpatialIndexManager` with no bounds argument (`layoutStore.ts`), so it defaults to `QUADTREE_CONFIG.DEFAULT_BOUNDS` — `{x: -10000, y: -10000, width: 20000, height: 20000}` (`constants.ts`).
- `QuadNode.insert` returns `false` for anything not fully contained (`QuadTree.ts`), and `SpatialIndexManager.insert` discards that return value.
- `QuadTree.update` early-returns for an id not in `itemMap`, so a node dropped once is never recovered — even if it later moves back inside the box.

A 3000-node workflow built by tiling the default graph spans roughly 48,000 units, so the majority of its nodes are absent from the index.

## Impact
Anything reading the shared index gets silently partial results. Today that is hit-testing and selection paths; it would also have made viewport culling render far-flung nodes permanently invisible, which is why #15030 uses a private index sized to the graph extent rather than the shared one.

## Suggested fix
Size the root to the actual graph extent (rebuilding on outgrow), or keep an overflow list for out-of-bounds items. Either way, stop discarding `insert`'s return value.

Found during review of #15030 by @christian-byrne.

Contributor guide

Open the contributing guide

Research direction

Start with layoutStore.ts, constants.ts, and QuadTree.ts to trace the shared index bounds, insertion return value, and update behavior. Compare the shared index with the private graph-sized index described in #15030. Done means nodes outside the default ±10000 box are retained, queryNodesInBounds and hit-testing return them, and moving a previously dropped node back inside the bounds works.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.