Comfy-Org / Comfy-Org/ComfyUI_frontend

A chained preview exposure is dropped when its leaf shares a local node id with a sibling interior node

Open
#16,657 1 comment 0 reactions 1 assignee Claimed by @DrJKL View on GitHub
area:previews area:subgraph Potential Bug
Dominant language
TypeScript
Stars
2k
Forks
699
Avg merge
1d 7h
Merged PRs (30d)
490

Description

## Problem

When a subgraph host promotes both its own interior node and, through a nested subgraph, a node that happens to carry the same local id, the chained preview never renders. The host shows only its own.

Node ids restart at 1 in every graph, so "the host's node 3" and "a nested subgraph's node 3" are ordinary neighbours rather than a contrived case. `usePromotedPreviews.ts:156` labels each display item with the chain-resolved *leaf* id, which belongs to the nested subgraph's id space, while sibling entries use the host's own id space — the two are compared and keyed as if they were the same namespace.

## Evidence

Fixture: `Host A` (root node 1) exposes its own sampler (node 3) and, via `Nested B` (node 5), that subgraph's sampler — also numbered 3. Live preview frames driven at `1:3` and `1:5:3`:

| frames sent | previews rendered on `Host A` |
| --- | --- |
| `1:3` only | 1 |
| `1:5:3` only | **0** |
| both | **1** |
| both, control fixture with the nested leaf renumbered to 7 (`1:5:7`) | **2** |

The control isolates the shared local id as the cause: the same chain, the same exposures, the same frames — only the leaf's number differs, and it renders correctly.

The entry is lost before it reaches the renderer, not by the `v-for` key: no Vue duplicate-key warning is emitted, so `usePromotedPreviews` is emitting one entry rather than two colliding ones. I did not isolate which step of the chain resolution swallows it.

Repro is in #16654 (`browser_tests/tests/subgraph/subgraphPreviewIdentity.spec.ts`, the last two scenarios). That PR is verification-only and not for merging.

## Reachability

Colliding interior ids only survive a load with `Comfy.Graph.DeduplicateSubgraphNodeIds` set to `false`, which the repro test sets — the default-on deduplication otherwise renumbers one of them. So this is narrower than it first looks, but the setting is user-facing, and the same identifier shape is what the first-hop exclusion-set workaround in `mergeSubgraphPreviews` (added in #14569) exists to route around.

## Provenance

* **Found by:** building reproductions while reviewing #14569
* **How:** hand-built colliding-id and unique-id fixture pair, drove frames individually and together, and checked the browser console for duplicate-key warnings to rule out the render key
* **Confidence:** the behavior and its cause (shared local id) are verified by execution at `52f6404d3` with a live backend; the exact step inside chain resolution is not identified
* **Predates #14569.**

## Suggested direction

`leafExecutionId` is already computed at `usePromotedPreviews.ts:140` and discarded one line later, and `useAmbientSubgraphPreviews` likewise already holds its appended execution id. Carrying that on the display item instead of the bare leaf id — renamed accordingly — would make these identifiers unique by construction. `PromotedPreview` is runtime-only, so the persisted `previewExposures` shape is unaffected, and its only consumers are the render key in `LGraphNode.vue:166` and `mergeSubgraphPreviews`; `NodeContent` reads just `type` and `urls`.

## Related

* #14569 — introduces `mergeSubgraphPreviews`, whose first-hop exclusion set works around the same namespace mismatch from the other direction.
* #10718 — centralizing preview promotion; a natural place to settle preview identity once rather than per call site.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.