fix(validate): only enforce promoted hard checks on output-reachable nodes (BE-3406)#565
fix(validate): only enforce promoted hard checks on output-reachable nodes (BE-3406)#565mattmillerai wants to merge 2 commits into
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 4 finding(s).
| Severity | Count |
|---|---|
| 🟠 High | 1 |
| 🟡 Medium | 1 |
| 🟢 Low | 2 |
Panel: 6/8 reviewers contributed findings.
Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)
…ify demoted range warnings (BE-3406) Cursor-review follow-ups on PR #565: - Guard non-dict `inputs` in both the per-input loop and the `_output_reachable_node_ids` walk: a truthy non-dict value slipped past `or {}` and crashed `.items()`/`.values()` with an unhandled traceback instead of returning structured errors. - Screen unhashable class_type (list/dict) in `Graph.node()`, coerce a non-str class_type to "" in the main loop, and route the linked-source lookup through the guarded `self.node()` — a `dict.get` on an unhashable key raised TypeError across the reachability walk and lookup sites. - Fully qualify the `field` of a range violation demoted to a warning on a pruned node (`node.class.input`), matching every other warning's schema that preflight renders via `w["field"]`. Adds TestValidateMalformedInputs (non-dict inputs, unhashable class_type must not crash) and a demoted-warning field-format assertion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
🤖 The reviews loop filed Linear follow-up ticket(s) for review thread(s) deferred as out of scope for this PR:
|
…nodes (BE-3406) ComfyUI's validate_prompt only validates output nodes and their transitive input ancestors; nodes not reachable from any output are pruned and never validated. #551's promoted hard checks (required_input_missing, autogrow_no_slots, below_min/above_max) ran for every recognized node, hard-rejecting a disconnected/incomplete node the server would silently drop (esp. a required LINK input the frontend omits when disconnected). Compute the output-reachable node set by walking input link references backward from every output node, and restrict the required-presence and range hard errors to that set. Out-of-range values on pruned nodes are demoted back to advisory warnings. Edge/shape/enum checks are unchanged (pre-existing behavior, out of scope). Three #551 tests whose single node had no output are updated to wire that node to a SaveImage so the promotion is asserted where the server enforces it.
…ify demoted range warnings (BE-3406) Cursor-review follow-ups on PR #565: - Guard non-dict `inputs` in both the per-input loop and the `_output_reachable_node_ids` walk: a truthy non-dict value slipped past `or {}` and crashed `.items()`/`.values()` with an unhandled traceback instead of returning structured errors. - Screen unhashable class_type (list/dict) in `Graph.node()`, coerce a non-str class_type to "" in the main loop, and route the linked-source lookup through the guarded `self.node()` — a `dict.get` on an unhashable key raised TypeError across the reachability walk and lookup sites. - Fully qualify the `field` of a range violation demoted to a warning on a pruned node (`node.class.input`), matching every other warning's schema that preflight renders via `w["field"]`. Adds TestValidateMalformedInputs (non-dict inputs, unhashable class_type must not crash) and a demoted-warning field-format assertion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9915dd8 to
4295f0c
Compare
ELI-5
ComfyUI's server only checks the nodes that actually feed into an output (like Save Image), plus everything upstream of them. Any node left disconnected — dangling in an exported workflow — is quietly thrown away and never checked. But PR #551 added strict "you're missing a required input" / "value out of range" rejections that fired on every recognized node, including those disconnected ones. So
validatewould hard-reject a workflow the server would happily run (a disconnected node especially loses its required link inputs, which the frontend only serializes when connected). This PR teachesvalidateto do the same pruning the server does: figure out which nodes are reachable from an output, and only apply those promoted hard checks to them.What changed
_output_reachable_node_ids(workflow, graph): seeds from every output node (is_output_node) and walks input link references ([node_id, output_index]) backward — the same link predicate the rest ofvalidate_workflowuses — to compute the transitive-ancestor set the server would validate. Cycle-safe (dedupes via the reachable set); dangling references (node absent from the workflow) simply aren't traversed.validate_workflowrestricts the fix(validate): presence-check required inputs, no-outputs check, hard-error range violations (BE-3357) #551-promoted hard checks to reachable nodes:required_input_missing(_check_required_present) andautogrow_no_slots(_check_autogrow_required) are skipped for unreachable nodes.below_min/above_maxare demoted from hard errors back to advisory warnings on unreachable nodes (matching pre-fix(validate): presence-check required inputs, no-outputs check, hard-error range violations (BE-3357) #551 behavior for those nodes), via a new keyword-onlyrange_is_errorarg on_validate_catalog_value.shape_mismatch,unknown_enum_value,dangling_edge,output_index_out_of_range,edge_type_mismatch,autogrow_bare_input). These predate fix(validate): presence-check required inputs, no-outputs check, hard-error range violations (BE-3357) #551 and were not flagged as over-rejecting; scoping only the newly-promoted checks keeps the diff minimal and avoids broadening behavior the reviewers didn't raise.Tests
New (in
TestValidateServerParity):test_disconnected_node_missing_required_is_pruned— acceptance (a): disconnected node missing every required input, alongside a valid connected chain →valid: true.test_reachable_node_missing_required_still_errors— acceptance (b): node on the output chain missing a required input still hard-errors.test_transitive_ancestor_missing_required_still_errors— a two-hop-upstream ancestor is reachable and still validated (proves the backward walk follows edges, not just direct parents).test_output_node_missing_required_still_errors— an output node itself seeds the reachable set.test_disconnected_out_of_range_demoted_to_warning— out-of-range on a pruned node is a warning, not a hard error; chain stays valid.test_reachable_out_of_range_still_errors— the connected node still hard-errors on out-of-range.Updated:
test_below_min_error,test_above_max_error,test_required_autogrow_with_no_slots_errors(from #551) each had a single non-output node with no output chain — the server would prune those too (they'd hitprompt_no_outputs, never range/required-checked). Wired the tested node to aSaveImageso the promotion is asserted where the server actually enforces it.uv run --extra dev pytest tests/comfy_cli/cql/→ 152 passed.ruff check+ruff format --checkclean.Notes / judgment calls
matt/be-3357-validate-required-inputs, base of this PR) — the promoted hard checks this PR scopes only exist on that branch, not onmain. GitHub will retarget this PR tomainwhen fix(validate): presence-check required inputs, no-outputs check, hard-error range violations (BE-3357) #551 merges.autogrow_bare_input(a mis-wiring/shape check, distinct from the required-_check_autogrow_requiredno-slots check) is likewise left as-is.Deferred from a review thread on #551 (BE-3406).