From 9dc6203b3d24125b829ac902c8f8cbf51c087125 Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Thu, 19 Feb 2026 21:29:17 -0800 Subject: [PATCH] docs: document subgraph limitations with autogrow and matchtype (#8709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Document why autogrow and matchtype don't work inside subgraphs, covering root cause, symptoms, workarounds, and historical context. ## Changes - **What**: Add `src/core/graph/subgraph-dynamic-input-limitations.md` explaining the static-vs-dynamic impedance mismatch between subgraph slots (fixed type at creation) and matchtype/autogrow (runtime mutations). Includes Mermaid diagrams, workarounds, and PR history. Link added to `src/lib/litegraph/AGENTS.md` for discoverability. ## Review Focus - Accuracy of the technical explanation — @AustinMroz authored matchtype/autogrow, @webfiltered authored the subgraph system - Whether the workarounds section is practical and complete - File placement: colocated at `src/core/graph/` next to both `subgraph/` and `widgets/dynamicWidgets.ts` ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8709-docs-document-subgraph-limitations-with-autogrow-and-matchtype-3006d73d36508134a64ce8c2c49e05f1) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action --- .../subgraph-dynamic-input-limitations.md | 52 +++++++++++++++++++ src/lib/litegraph/AGENTS.md | 4 ++ 2 files changed, 56 insertions(+) create mode 100644 src/core/graph/subgraph-dynamic-input-limitations.md diff --git a/src/core/graph/subgraph-dynamic-input-limitations.md b/src/core/graph/subgraph-dynamic-input-limitations.md new file mode 100644 index 0000000000..9ab31faee6 --- /dev/null +++ b/src/core/graph/subgraph-dynamic-input-limitations.md @@ -0,0 +1,52 @@ +# Subgraph Limitations: Dynamic Inputs (MatchType / Autogrow) + +MatchType and autogrow do not work inside subgraphs. Subgraph boundary slots freeze their type at connection time — whatever type exists at that moment is permanently captured as a fixed string. There is no runtime type resolution or reactivity across the boundary: matchtype mutations and autogrow slot additions on internal nodes are never propagated to the `SubgraphNode`. + +```mermaid +flowchart LR + subgraph Parent Graph + SN[SubgraphNode] + end + subgraph Inside Subgraph + SIN[SubgraphInputNode] + N[Node with matchtype/autogrow] + end + + SN -- "mirrors slots on\nconfigure & input-added" --> SIN + SIN -- "type frozen as string\non addInput()" --> N + N -. "runtime type changes\nNOT propagated" .-> SIN + SIN -. "no type update path" .-> SN + + classDef static fill:#1a1a2e,stroke:#e94560,color:#eee + classDef dynamic fill:#1a1a2e,stroke:#0f3460,color:#eee + class SN,SIN static + class N dynamic +``` + +## MatchType + +`SubgraphInputNode.connectByType` captures the type as a fixed string via `subgraph.addInput(name, String(type))`. `SubgraphNode` mirrors each new input via the `input-added` event, copying the type at that moment. + +The subgraph boundary slot type is frozen at connection time with no subsequent reactivity. If the first connection carries a specific type (e.g., `IMAGE`), the slot is correctly typed and incompatible connections are properly blocked on the `SubgraphNode`. However, if the first connection carries `*` (any type) — for example from a switch node — the slot is permanently set to `*`, accepting any connection regardless of the internal node's actual type requirements. + +## Autogrow + +Autogrow hooks `onConnectionsChange` and splices new inputs into the node's `inputs` array when the last slot is connected. These inputs are added to the **internal node**, not to the subgraph's input/output definitions. `SubgraphNode` only listens for events on the subgraph definition — there is no bridge. + +Open UX questions (from the autogrow author): + +- Should promoting an autogrow connection cause the `SubgraphNode` to autogrow from that slot? +- How to distinguish "promote this specific input" vs "promote the autogrow behavior"? + +## Workarounds + +- Use explicitly typed subgraph inputs instead of relying on matchtype at the boundary. +- Move matchtype/autogrow nodes outside the subgraph; pass stable typed values in. + +## References + +- `src/core/graph/widgets/dynamicWidgets.ts` — `applyMatchType`, `applyAutogrow` +- `src/lib/litegraph/src/subgraph/SubgraphInputNode.ts` — `connectByType` +- `src/lib/litegraph/src/subgraph/SubgraphNode.ts` — `input-added` event listener +- [#8352](https://github.com/Comfy-Org/ComfyUI_frontend/pull/8352) (closed) — attempted fix, unresolved edge cases +- [#7837](https://github.com/Comfy-Org/ComfyUI_frontend/pull/7837) (merged) — partial fix only diff --git a/src/lib/litegraph/AGENTS.md b/src/lib/litegraph/AGENTS.md index 3ba1f698eb..49d73b5051 100644 --- a/src/lib/litegraph/AGENTS.md +++ b/src/lib/litegraph/AGENTS.md @@ -28,6 +28,10 @@ import { LGraph } from '@/lib/litegraph/src/LGraph' **Root cause**: `LGraph` ↔ `Subgraph` circular dependency (Subgraph extends LGraph, LGraph creates Subgraph instances). +## Known Limitations + +- Subgraph dynamic input limitations (autogrow/matchtype): see [`src/core/graph/subgraph-dynamic-input-limitations.md`](../../core/graph/subgraph-dynamic-input-limitations.md) + ## Test Helpers ```typescript