Comfy-Org / Comfy-Org/ComfyUI_frontend
fix: fresh SubgraphNode instances leak promoted widget values through shared inner-widget state
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
## Problem
Multiple SubgraphNode instances sharing the same subgraph blueprint leak promoted widget values to each other when the value is set through the promoted view on one instance but never explicitly set on siblings.
**Root cause**: The `PromotedWidgetView` value setter writes to both `_instanceWidgetValues` (per-instance) AND shared state (widget state store, `resolveAtHost().widget.value`). The getter checks `_instanceWidgetValues` first, but for fresh instances (never explicitly set), it falls through to shared state — which was polluted by a sibling's setter.
This affects both display (`value` getter) and execution (`serializeValue` falls through to `this.value`).
## Reproduction
1. Create two SubgraphNode instances from the same blueprint
2. Edit a promoted widget on instance A
3. Read the same widget on instance B → returns A's value instead of the default
## Investigation (from PR #10849)
Three approaches were tried:
1. **Seed `_instanceWidgetValues` at creation** — breaks nested subgraph propagation (direct inner widget changes like `comboWidget.value = 'b'` are shadowed by the seed)
2. **Remove shared state writes from setter** — breaks 12 tests (linked widget cascading, three-level nested propagation, rendering sync)
3. **Skip widget state store in getter** — setter also writes to `resolveAtHost().widget.value`, so the fallback still picks up polluted values
## Proposed solutions
- **Inner widget observer**: Add a change listener on the concrete inner widget so `_instanceWidgetValues` stays in sync with direct mutations. This lets the getter use only the per-instance map.
- **Sole source of truth**: Make `_instanceWidgetValues` the exclusive read path for the getter. Move all shared state syncing (for rendering, linked widgets) to a separate concern that runs when an instance becomes the active/focused one.
Both require architectural changes to the value propagation flow.
## Related
- PR #10849 — per-instance widget values (configure/serialize path)
- Issue #10146 — original shared-value collision bug
┆Issue is synchronized with this [Notion page](https://www.notion.so/Issue-10981-fix-fresh-SubgraphNode-instances-leak-promoted-widget-values-through-shared-inner-wi-33d6d73d365081b0af4ae40d68c5c228) by [Unito](https://www.unito.io)
Contributor guide
Assessment
This issue has not been assessed yet.