feat: validate auto-converts UI-format workflows like comfy run (BE-3359)#553
feat: validate auto-converts UI-format workflows like comfy run (BE-3359)#553mattmillerai wants to merge 2 commits into
comfy run (BE-3359)#553Conversation
…-3359) Detect frontend/UI-export workflows in `comfy validate` and lower them to API format with the existing convert_ui_to_api before validating, exactly as `comfy run` does. Previously a UI export validated vacuously (each wrapper key emitted a non_node_key warning, zero nodes checked, verdict valid:true). Graph now retains the raw object_info it was built from (Graph.object_info), so the converter reuses it with no second fetch and offline --input keeps working. The JSON envelope gains converted_from_ui + converted_node_count.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 55 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 (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
🔍 Cursor Review — Consolidated panel
Triggered by @mattmillerai.
Found 2 finding(s).
| Severity | Count |
|---|---|
| 🟢 Low | 2 |
Panel: 6/8 reviewers contributed findings.
Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)
Per Cursor review: object_info returns the graph's live internal schema state by reference; document that callers must not mutate it (a defensive copy of the ~11KB payload on every access is not worth the cost, and the only consumer, convert_ui_to_api in validate, reads it).
ELI-5
If you hand
comfy validatea workflow you exported from the ComfyUI canvas(the "UI" shape with
nodes/linksarrays), it used to shrug and say"✓ valid" — while actually checking nothing. Every wrapper key (
nodes,links,groups,config, …) just tripped a "this isn't a node" warning, noreal nodes were checked, and you got a cheerful but meaningless pass.
Now
validatenotices the UI shape and quietly converts it to the API shapefirst — the exact same lowering
comfy runalready does — and validates thereal graph. So you get a truthful answer, and the JSON tells you it validated
the converted graph.
What changed
comfy_cli/cmdline.py(validate): after loading the workflow + graph andbefore
graph.validate_workflow(...), detect UI format with the existingis_ui_workflowpredicate and, when it matches, convert withconvert_ui_to_api(...)— mirroringcomfy run. On aWorkflowConversionErroror an empty conversion, emit the structured
workflow_not_api_formaterror(exit 1) naming the conversion; an unexpected converter crash maps to
conversion_crash(like run) so the agent flow never sees a raw traceback. Onsuccess the converted graph is validated and the JSON envelope gains
converted_from_ui: true+converted_node_count.comfy_cli/cql/engine.py(Graph):Graphnow retains the raw/object_infoit was built from and exposes it asGraph.object_info. Theconverter reuses this — no second fetch, and offline
--inputstillsupplies both the graph and the converter's object_info from one file.
No
engine.pyvalidation-logic change: once conversion runs before the nodeloop, the wrapper-key
non_node_keynoise disappears as a side effect;non_node_keykeeps its correct meaning for genuinely stray keys in API files.Tests (
tests/comfy_cli/command/test_validate_command.py, new)All run offline via
--inputagainst the existing sd15 fixtures:valid:true,converted_from_ui:true,converted_node_count:7,zero
non_node_keywarnings (the BE-3349 repro, now truthful).valid:false+unknown_class_type(real problem surfaced) with
converted_from_ui:true.workflow_not_api_format, message names the conversion.converted_from_uikey.Judgment calls
typenode → expectworkflow_not_api_format. Empirically that input does convert (to a nodewith that class_type), so it surfaces as
valid:false/unknown_class_typeinstead — which is arguably the more useful outcome and matches the acceptance
criterion ("
valid:falseon real problems in the converted graph"). I coverboth: unknown-type →
valid:false, and a genuinely empty conversion (nodeswith no
type) →workflow_not_api_format.conversion_crashbranch (not spelled out in the ticket butpart of run's handling it says to mirror) so an unexpected converter failure
returns a structured error rather than a traceback — the MCP pre-flight flow
this ticket serves depends on structured output.
Graph.object_infois a small additive accessor (public property) — noexisting behavior changed; it just exposes the raw dict
from_object_infoalready received.
Not a capability denial
The new
workflow_not_api_format/conversion_crashexits only fire when theproduct's own converter (
convert_ui_to_api, the same onecomfy runuses)genuinely fails on that file — verified empirically. This PR adds the
UI-validation capability that was silently absent; it does not deny one that
exists elsewhere.
Test status
New suite: 6/6 pass. Full suite: 2570 passed, 9 pre-existing failures unrelated
to this change (tomlkit multiline-comment breakage in
registry/test_config_parser.py+nodes/test_node_init.py, tracked separatelyas BE-3290 —
ValueError: Comment cannot contain line breaks; none touchvalidate/Graph).ruff check+ruff format --checkclean.