Skip to content

Conversation

AustinMroz
Copy link
Collaborator

@AustinMroz AustinMroz commented Oct 15, 2025

The toConcrete call creates a restricted view of a widget that extends from BaseWidget. A copy of the widget created by createCopyForNode will also inherit this restricted view. This creates two problems

  • Some widget properties (like displayValue) have been judged unsafe and are explicitly blacklisted from being copied
  • The widget now extends from BaseWidget. This results in the widget being processed differently in some logic, such as #processWidgetClick
    • Because LegacyWidget provides an implementation for onClick, the presence of click handlers can not be used to determine which should be used.

As a proposed, minimal workaround. Widgets which do not already extend from BaseWidget are no longer cloned through createCopyForNode.

Because this PR involves side-stepping properties which have been explicitly blacklisted. I'd recommend waiting to merge/backport until after the release of 1.28.7

Resolves Kosinkadink/ComfyUI-VideoHelperSuite#569

┆Issue is synchronized with this Notion page by Unito

@github-actions
Copy link

github-actions bot commented Oct 15, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 10/15/2025, 09:06:02 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Oct 15, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 10/15/2025, 09:21:28 PM UTC

📈 Summary

  • Total Tests: 499
  • Passed: 467 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 458 / ❌ 0 / ⚠️ 2 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Oct 15, 2025
@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Oct 17, 2025
this
)
const promotedWidget =
widget instanceof BaseWidget
Copy link

Choose a reason for hiding this comment

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

[architecture] high Priority

Issue: Type safety concern - no runtime type checking for BaseWidget instanceof check
Context: The instanceof check relies on runtime type information which could fail if widgets are created through different contexts or loaded modules
Suggestion: Add explicit type checking or use duck typing to verify the widget has createCopyForNode method before calling it

const promotedWidget =
widget instanceof BaseWidget
? widget.createCopyForNode(this)
: { ...widget, node: this }
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Inconsistent widget copying strategies may lead to different behavior
Context: BaseWidget instances use createCopyForNode() which may have different copying semantics than object spread with node assignment
Suggestion: Document the differences between these approaches or consider unifying the widget copying strategy to ensure consistent behavior

const promotedWidget =
widget instanceof BaseWidget
? widget.createCopyForNode(this)
: { ...widget, node: this }
Copy link

Choose a reason for hiding this comment

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

[security] low Priority

Issue: Object spread may inadvertently copy unsafe properties from untrusted widgets
Context: The spread operator {...widget} copies all enumerable properties, potentially including functions or references that weren't intended to be cloned
Suggestion: Use a more explicit copying approach that only copies known safe properties, similar to how BaseWidget.constructor already filters out unsafe properties

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: Prevent partial copy of custom widgets when performing linked promotion on subgraphs (#6079)
Impact: 5 additions, 4 deletions across 1 file

Issue Distribution

  • Critical: 0
  • High: 1
  • Medium: 2
  • Low: 2

Category Breakdown

  • Architecture: 2 issues
  • Security: 1 issue
  • Performance: 0 issues
  • Code Quality: 2 issues

Key Findings

Architecture & Design

The PR introduces a conditional approach to widget copying that addresses the original issue of restricted widget views being propagated through createCopyForNode. However, it introduces type safety concerns around instanceof checks and potential inconsistencies between the two copying strategies.

The change moves away from the centralized toConcreteWidget function which provided consistent widget transformation logic, potentially fragmenting widget handling across the codebase.

Security Considerations

The object spread operation ({...widget, node: this}) for non-BaseWidget instances could inadvertently copy unsafe properties. The original BaseWidget constructor already has logic to filter out potentially dangerous properties (displayValue, outline_color, etc.), but the spread approach bypasses this safety mechanism.

Performance Impact

No significant performance concerns identified. The instanceof check is a lightweight operation and the elimination of the toConcreteWidget call may actually provide minor performance benefits.

Integration Points

This change affects the subgraph widget promotion system, which is a core part of the nested workflow functionality. The dual copying strategies could lead to subtle differences in behavior between legacy and BaseWidget-derived widgets.

Positive Observations

  • The change addresses a real issue with toConcrete creating restricted widget views
  • Import cleanup is correctly done (toConcreteWidget is not used elsewhere)
  • The solution is minimal and targeted to the specific problem
  • Preserves backward compatibility with existing widget types

References

Next Steps

  1. Address the type safety concerns around instanceof checks
  2. Consider using duck typing or explicit method checking for better reliability
  3. Document the differences between the two widget copying strategies
  4. Consider adding unit tests to verify both code paths work correctly
  5. Review if similar pattern needs to be applied elsewhere in the codebase

This is a comprehensive automated review. For architectural decisions requiring human judgment, please request additional manual review.

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Oct 17, 2025
@christian-byrne
Copy link
Contributor

This PR is only 9 LOC, but there's a lot of history, depth, and complexity to it, haha.

@AustinMroz
Copy link
Collaborator Author

Yeah. Wound up merging the proposed workaround in VHS so there's no rush here. Probably best I do some more digging and add test cases for each of the edge cases that can cause things to break here.

@AustinMroz
Copy link
Collaborator Author

AustinMroz commented Oct 17, 2025

Some more note taking.

  • Blacklisting was added by Workaround crash on load from custom nodes litegraph.js#1023
    • The blacklisting is just a list of BaseWidget properties which only have getters
      • Thus, custom node props wasn't a factor at time of creation... Shouldn't be an issue now.
    • Blacklisting displayValue instead of _displayValue is a bug?
      • displayValue was changed from _displayValue due to a conflict with VHS, but the value in VHS is a safe, well-behaved, function
  • The existing implementation createCopyForNode is only a shallow copy
    • (Making a change to widget.options.min also changes promotedWidget.options.min)
  • Spread skips properties inherited from prototypes
    • This makes it inherently incomplete. Should be avoided?
  • {__proto__: widget}? Still breaks private props/getters. Probably safer, but Alex has declared disain.
    • Perhaps combining? {...widget, __proto__: widget} is less shallow, but still struggles with getters/private props

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants