Skip to content

Conversation

@AustinMroz
Copy link
Contributor

Subgraphs are loaded in order of creation. Under most circumstances, this means newer subgraphs are loaded first. With nested subgraphs, this means a subgraph node has it's inputs connected before it's inside is loaded. When the inner subgraph is loaded, input-added events are triggered even though inputs already exist on the subgraph node.

This is resolved by adding a check for if an input of the corresponding name already exists when adding an input.

Subgraphs are loaded in order of creation. Under most circumstances,
this means newer subgraphs are loaded first. With nested subgraphs, this
means a subgraph node has it's inputs connected before it's inside is
loaded. When the inner subgraph is loaded, input-added events are
triggered even though inputs already exist on the subgraph node.

This is resolved by adding a check for if an input of the corresponding
name already exists when adding an input.
christian-byrne
christian-byrne approved these changes Aug 5, 2025
@christian-byrne
Copy link
Contributor

Testing Recommendation

This bug highlights a gap in our test coverage for subgraph deserialization scenarios. We should add unit tests to prevent regression:

Suggested Test Cases

  1. Test loading nested subgraphs with pre-existing connections

    it('should not duplicate inputs when loading nested subgraphs with existing connections', () => {
      // Create a subgraph node with inputs already connected
      // Then trigger subgraph definition loading
      // Verify no duplicate inputs are created
    })
  2. Test the idempotency of input-added event handler

    it('should handle input-added events idempotently during deserialization', () => {
      // Create SubgraphNode with existing inputs
      // Manually dispatch input-added events for same inputs
      // Verify input count remains unchanged
    })
  3. Test the complete serialization/deserialization cycle

    it('should correctly restore nested subgraphs without duplication', () => {
      // Create nested subgraph structure
      // Serialize to JSON
      // Deserialize and verify structure integrity
    })

These tests would help catch similar issues in the future and ensure the event system handles both runtime and loading scenarios correctly.

christian-byrne
christian-byrne previously approved these changes Aug 5, 2025
Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR fixes a loading order issue where nested subgraphs loaded in creation order can cause duplicate inputs.

The problem occurs when:

  • SubgraphNode has inputs connected before its inner subgraph loads
  • Inner subgraph loading triggers input-added events for already-existing inputs
  • The event handler adds duplicate inputs

The SubgraphNode constructor listens for input-added events:
subgraphEvents.addEventListener("input-added", (e) => {
const { name, type } = e.detail.input
this.addInput(name, type) // Runs even if input exists
})

The fix adds a guard to check for existing inputs:
if (this.inputs.find((i) => i.name == name))
return

This minimal fix preserves runtime synchronization while preventing duplication during loading. The event system was designed for runtime changes, not deserialization scenarios where state already exists.

Approved - clean fix that addresses the root cause.

@christian-byrne
Copy link
Contributor

Can we change the find to some to satisfy the linter?

@AustinMroz
Copy link
Contributor Author

Absolutely. Will look into fixing my setup so it happens automatically like it does for frontend.

@christian-byrne
Copy link
Contributor

Thank you. Soon, we will merge litegraph and frontend into a single repo. Details here: Comfy-Org/ComfyUI_frontend#4667. We should make an ADR as well so all contributors are involved in the change.

@christian-byrne christian-byrne merged commit a01bca6 into Comfy-Org:master Aug 5, 2025
4 checks passed
benceruleanlu added a commit to Comfy-Org/ComfyUI_frontend that referenced this pull request Aug 5, 2025
Subgraphs are loaded in order of creation. Under most circumstances,
this means newer subgraphs are loaded first. With nested subgraphs, this
means a subgraph node has it's inputs connected before it's inside is
loaded. When the inner subgraph is loaded, input-added events are
triggered even though inputs already exist on the subgraph node.

This is resolved by adding a check for if an input of the corresponding
name already exists when adding an input.

Port of Comfy-Org/litegraph.js#1192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants