UI→API conversion ignores host values on a legacy proxyWidgets subgraph instance (convert path never runs flush_proxy_migration)

Abierto
#1,070 4 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
1-2 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
backend, cli

Línea de trabajo

Start with comfy_cli/workflow_to_api.py, especially _overlay_promoted_host_values, then read flush_proxy_migration in comfy_cli/cql/promoted.py and its existing call sites in workflow_ops.py and cql/engine.py. Reproduce with node 252 in tests/comfy_cli/fixtures/gallery/template_horizontal_vertical_extension.json; check whether conversion preserves the host value 9:16 rather than using the interior default. The suggested change is to run migration on an isolated copy before overlaying host values.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

effort:small

Summary

convert_ui_to_api never runs the legacy proxyWidgets forward migration, so a subgraph instance whose promotion is still a legacy properties.proxyWidgets entry converts with its host-owned values ignored. The interior widget's default is submitted instead.

flush_proxy_migration (comfy_cli/cql/promoted.py:1985) is a full port of the frontend's flushProxyWidgetMigration, and it is called from exactly two places:

  • comfy_cli/workflow_ops.py:3458
  • comfy_cli/cql/engine.py:5533

Both are write paths. comfy_cli/workflow_to_api.py never calls it. Instead _overlay_promoted_host_values resolves promoted values through _promoted.promoted_inputs(sg, subgraph_defs) filtered to is_widget, which enumerates the definition's declared linked inputs. A legacy entry that the definition does not yet back with a linked input is invisible to that walk, so the host value attached to it is dropped.

The module docstring is explicit that the migration is the mechanism that makes a legacy promotion addressable (promoted.py:19-25), and that the CLI runs it "on the one instance whose legacy promotion a write is about to edit". Conversion is not a write, so it gets no migration.

Reproduction

On main @4d054af, using a fixture already in the repo — tests/comfy_cli/fixtures/gallery/template_horizontal_vertical_extension.json, node 252:

proxyWidgets (4): [["233","$$canvas-image-preview"], ["232","$$canvas-image-preview"],
                   ["234","$$canvas-image-preview"], ["285","aspect_ratio"]]
sg.inputs    (1): [["image","IMAGE"]]

The definition declares one input, and it is an IMAGE socket — no widget-backed linked inputs at all. Write the host values the way the frontend writes them, positionally in proxyWidgets order with the preview pseudo-widgets holding null:

inst["widgets_values"] = [None, None, None, "9:16"]
api = convert_ui_to_api(wf, object_info)
api["252:285"]["inputs"]["aspect_ratio"]
# -> "9:16 (Portrait Widescreen)"   the interior default
# expected "9:16"                   the host value

The user's choice is discarded and the graph validates and runs with a different aspect ratio.

Four more shipped gallery fixtures have the same shape — proxyWidgets longer than, or ordered differently from, the definition's inputs:

fixture node proxyWidgets sg.inputs
templates_graphic_design_recomposer.json 143 3 1
template_horizontal_vertical_extension.json 252 4 1
flux_dev_checkpoint_example.json 56 9 7
image_z_image_turbo.json 57 9 8
05_audio_ace_step_1_t2a_song_subgraphed.json 127 12 12

All five carry widgets_values: [], which is why no existing test catches this — with no host values stored, falling back to the interior default happens to be correct. The defect only appears once the host holds values, which is the state a user's own save is in.

Impact

The 2026-10 Comfy Hub conversion audit flagged this as its largest and most damaging finding: 25 of 392 public workflows. It is often silent — when the misassigned values share a type (cfg ↔ shift, two model filenames) the graph passes comfy workflow validate and runs on Cloud with the wrong settings. In the rest a prompt lands in a model-name field, which at least fails loudly.

Suggested fix

Run the same forward migration on an isolated copy before _overlay_promoted_host_values walks the instance, so conversion sees the same repaired state a write would. The migration is already deterministic (every minted id derived from (instance path, source node, widget)), already handles the cases the audit describes — $$-prefixed preview pseudo-widgets that own no slot, PrimitiveNode fan-out, control_after_generate companions, quarantine of unrepairable entries — and already picks host values positionally in proxyWidgets order (pickHostValue). Conversion needs its result, not a second implementation of it.

Relationship to other work

  • #1039 fixes a different half of promoted-value loss — a promoted value feeding a socket-only interior input — for promotions that are already backed by linked inputs. It does not add a migration step, so it does not cover this. Verified against its head: 13/13 parity, 99 promoted tests pass, and the fixture above still converts wrong.
  • #862 runs the migration before the first host write in the two slot-editing paths (closing #858's write-order bug). Same function, different call sites; it does not touch workflow_to_api.py. It is also currently conflicting and has had no activity since 2026-09-10.
  • #974 is the socket-target case #1039 addresses.

So this is uncovered by all three.

Cross-converter note

@comfyorg/api-to-workflow resolves promoted values through the proxyWidgets chain directly (comfy-cloud-mcp-server/src/converter/converter.ts:1571 resolveProxyWidgetValue), so it does not have this bug. The two converters therefore disagree on any legacy-promotion graph, and conversionParity.test.ts would show it — except that suite is skip-gated on comfy-cli being importable and CI installs no Python, so it never runs.

Lenguaje dominante
Python
Estrellas
1k
Forks
176
Merge medio
1 d 11 h
PR fusionados (30 d)
87

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Comfy-Org/comfy-cli

Todos los issues de Comfy-Org/comfy-cli

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.