fix(subgraph): preserve disambiguator on legacy -1 entry resolution

_resolveLegacyEntry now returns a full PromotedWidgetSource rather than a
bare [nodeId, widgetName] tuple, carrying disambiguatingSourceNodeId when
the resolved input widget is a nested PromotedWidgetView.

Without this, legacy -1 entries in nested subgraphs resolved to a key
'${source}:${widget}' while the promoted view registered under
'${source}:${widget}:${disambig}', causing the per-instance value
hydration lookup to miss silently. Values then fell back to inner-widget
delegation instead of the saved per-instance state.

Addresses CodeRabbit Major finding on PR #11559.
This commit is contained in:
dante01yoon
2026-04-24 18:26:10 +09:00
parent c9138e3894
commit 968a2fd9a5

View File

@@ -707,7 +707,7 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
private _resolveLegacyEntry(
widgetName: string
): [string, string] | undefined {
): PromotedWidgetSource | undefined {
// Legacy -1 entries use the slot name as the widget name.
// Find the input with that name, then trace to the connected interior widget.
const input = this.inputs.find((i) => i.name === widgetName)
@@ -715,19 +715,31 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
// Fallback: find via subgraph input slot connection
const resolvedTarget = resolveSubgraphInputTarget(this, widgetName)
if (!resolvedTarget) return undefined
return [resolvedTarget.nodeId, resolvedTarget.widgetName]
return {
sourceNodeId: resolvedTarget.nodeId,
sourceWidgetName: resolvedTarget.widgetName
}
}
const widget = input._widget
if (isPromotedWidgetView(widget)) {
return [widget.sourceNodeId, widget.sourceWidgetName]
return {
sourceNodeId: widget.sourceNodeId,
sourceWidgetName: widget.sourceWidgetName,
...(widget.disambiguatingSourceNodeId && {
disambiguatingSourceNodeId: widget.disambiguatingSourceNodeId
})
}
}
// Fallback: find via subgraph input slot connection
const resolvedTarget = resolveSubgraphInputTarget(this, widgetName)
if (!resolvedTarget) return undefined
return [resolvedTarget.nodeId, resolvedTarget.widgetName]
return {
sourceNodeId: resolvedTarget.nodeId,
sourceWidgetName: resolvedTarget.widgetName
}
}
/** Manages lifecycle of all subgraph event listeners */
@@ -1142,7 +1154,7 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
if (nodeId === '-1') {
const legacy = this._resolveLegacyEntry(widgetName)
if (legacy) {
resolved = { sourceNodeId: legacy[0], sourceWidgetName: legacy[1] }
resolved = legacy
} else {
if (import.meta.env.DEV) {
console.warn(