`workflow set-slot` silently shifts every promoted widget when a legacy proxyWidgets slot is written after the others
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 68/100
調査の方向性
提供された workflow set-slot、workflow slots、workflow validate コマンドで失敗を再現し、その後 comfy_cli/cql/promoted.py、特に set_host_value と proxyWidgets の migration flush を読みます。あらゆる書き込み順序と、単一呼び出しおよび複数呼び出しによる更新をカバーする回帰 fixture またはテストを追加します。完了の条件は、widgets_values、変換された API グラフ、スロットラベルが順序に関係なく同一であり、validation が成功することです。
索引モデルが issue の本文から書いたものです。
説明
This issue was written and filed by an AI coding agent working under the seconds-0 account. Every claim below was reproduced on a real machine on 2026-09-07 and again on 2026-09-08. A human reviewed it before filing.
What happens
On the built-in template image_flux2_klein_text_to_image, one workflow set-slot call that writes several promoted widgets and puts 75.noise_seed last reports applied for every value with no warning. But the graph is now wrong. Every promoted widget on subgraph node 75 has moved one position:
75:69 PrimitiveInt {"value": "flux-2-klein-4b.safetensors"} <- model filename landed in the seed primitive
75:70 UNETLoader {"unet_name": "qwen_3_4b.safetensors"} <- got the CLIP name
75:71 CLIPLoader {"clip_name": "flux2-vae.safetensors"} <- got the VAE name
75:72 VAELoader {"vae_name": ""}
comfy --json workflow slots on the file shows the damage (75.value_1 = 'flux-2-klein-4b.safetensors', 75.unet_name = 'qwen_3_4b.safetensors', 75.text = 1024), and workflow validate rejects it with four errors. If an agent skips validation and runs it, the server rejects it. If the values happen to be the right type, it would generate the wrong thing.
Writing the seed first in the same call produces a correct graph every time.
Steps to reproduce
Needs comfy-cli 1.20.0 and any ComfyUI 0.34 server on 127.0.0.1:8188 (only for templates fetch and validate; no generation is needed).
comfy --json templates fetch image_flux2_klein_text_to_image -o /tmp/klein.ui.json
# BROKEN: seed last
cp /tmp/klein.ui.json /tmp/bad.ui.json
comfy --json workflow set-slot /tmp/bad.ui.json \
'75.unet_name=flux-2-klein-4b.safetensors' '75/62.steps=4' '75/63.cfg=1' \
'75.text=a lighthouse at dusk' '75.noise_seed=424242'
comfy --json workflow slots /tmp/bad.ui.json # 75.value_1 is now the model filename
comfy --json workflow validate --workflow /tmp/bad.ui.json # valid: false, 4 errors
# CORRECT: seed first
cp /tmp/klein.ui.json /tmp/good.ui.json
comfy --json workflow set-slot /tmp/good.ui.json \
'75.noise_seed=424242' '75.unet_name=flux-2-klein-4b.safetensors' '75/62.steps=4' '75/63.cfg=1' \
'75.text=a lighthouse at dusk'
comfy --json workflow validate --workflow /tmp/good.ui.json # valid: true
What we found by isolating it
Node 75 starts with widgets_values: []. Its subgraph declares six inputs (value, value_1, unet_name, clip_name, vae_name, text). noise_seed is a seventh promoted widget that comes from a legacy properties.proxyWidgets entry, outside that declared list. Single-variable tests on fresh copies:
| Overrides in one call | widgets_values of node 75 afterwards |
result |
|---|---|---|
unet_name only |
[1024, 1024, klein-4b, qwen, vae, ''] |
correct |
noise_seed only |
[1024, 1024, base-4b, qwen, vae, '', seed] |
correct |
noise_seed then unet_name |
[1024, 1024, klein-4b, qwen, vae, '', seed] |
correct |
unet_name then noise_seed |
[1024, klein-4b, qwen, vae, '', 1024, seed] |
shifted |
second call writing noise_seed on a file already materialized by an earlier call |
shifted | shifted |
all six with noise_seed first |
correct | correct |
So: once the six-entry array has been materialized, writing the proxyWidgets-backed slot moves value_1 behind text, and the UI-to-API converter then reads every promoted widget one position off. The code path is the legacy proxyWidgets handling in comfy_cli/cql/promoted.py (set_host_value and the proxy migration flush).
The same shift happens through comfy run-template -p ... with the seed last (rejected before submit with workflow_unknown_nodes, 4 errors) and through comfy-mcp's set_workflow_slot, which wraps the same code.
Why this matters for agents
Slot editing is the feature that lets an agent change a prompt or seed without hand-editing JSON. The command reports success, so an agent has no reason to re-check. The only defense today is "always list slots again and validate after every set-slot", which we now do, but the tool should not need that.
Environment
- comfy-cli 1.20.0, Python 3.13 (uv tool install)
- ComfyUI 0.34.6 (Comfy Desktop 1.0.46), macOS 15, Apple Silicon
- Template
image_flux2_klein_text_to_imageas shipped with ComfyUI 0.34.6
Related but different: #790 is about multi-type inputs in UI-to-API conversion. This one is about write order on promoted subgraph widgets.
Prompt for an agent to resolve this
You are working in the Comfy-Org/comfy-cli repository. Fix a bug in `workflow set-slot` (and the
shared slot engine used by `run-template -p` and comfy-mcp set_workflow_slot): on a subgraph node
whose promoted widgets include a legacy properties.proxyWidgets entry that is not in the subgraph's
declared input list, writing that slot AFTER other slots have materialized widgets_values shifts
every promoted widget one position, and the command still reports "applied" with no warning.
Reproduce first with comfy-cli 1.20.0 and any ComfyUI 0.34 server on 127.0.0.1:8188:
comfy --json templates fetch image_flux2_klein_text_to_image -o /tmp/klein.ui.json
comfy --json workflow set-slot /tmp/klein.ui.json '75.unet_name=flux-2-klein-4b.safetensors' \
'75/62.steps=4' '75/63.cfg=1' '75.text=a lighthouse at dusk' '75.noise_seed=424242'
comfy --json workflow slots /tmp/klein.ui.json
Confirm 75.value_1 now holds the model filename and 75.unet_name holds the CLIP name, and that
`workflow validate` reports 4 errors. Then confirm the same call with '75.noise_seed=424242' FIRST
produces a valid graph. Node 75 starts with widgets_values: []; its subgraph declares six inputs
(value, value_1, unet_name, clip_name, vae_name, text) and noise_seed is a seventh promoted widget
that comes from properties.proxyWidgets.
Find the cause in comfy_cli/cql/promoted.py (set_host_value and the proxyWidgets migration flush):
when the proxy-backed slot is written after the declared array exists, value_1 is moved behind text.
Fix it so write order never changes the resulting widgets_values layout, for both single-call and
multi-call sequences. Add a regression test using the shipped Klein template (or a minimal fixture
with the same shape: declared inputs plus one legacy proxyWidgets promotion) that writes the slots
in every order and asserts identical widgets_values and identical converted API graphs. Also make
`workflow slots` after the fix show each value under its own label. Do not add any AI attribution
to commits.
- 主要言語
- Python
- スター
- 1k
- フォーク
- 176
- 平均マージ
- 1日 11時間
- マージ済み PR(30日)
- 87
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Comfy-Org/comfy-cli のほかの issue
-
test_file_utils umask tests assert against a umask the code never reads (import-time _UMASK), so they only pass on a 0o022 host対応中かも @neverbiasu が 10 日前に担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
Comfy-Org/comfy-cli#907 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
Comfy-Org/comfy-cli#781 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
`comfy launch --background` fails with FileNotFoundError when comfy-cli is invoked by path対応中かも @RaphaelFakhri が 42 日前に担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Comfy-Org/comfy-cli#691 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Comfy-Org/comfy-cli#670 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
Comfy-Org/comfy-cli の issue をすべて見る
似ている issue
-
add entry to blockオープン
難易度 1/5 1時間未満 初心者へのやさしさ 65/100
StevenBlack/hosts#3299 ·
-
`garak --report` overwrites the input report when its name has no ".report"対応中かも @0z5a が今日担当しました。 オープンneeds-triage
難易度 2/5 半日 初心者へのやさしさ 72/100
メンテナーはふだん 2 日以内に返信
-
plot_graph crashes when a mesh node has no m2m edge対応中かも @tygvi が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
mllam/neural-lam#883 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
future-agi/future-agi#4092 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
transcript analytics: a text whose only protected spans the prose pass redacts is withheld wholeオープン
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
WingedGuardian/GENesis-AGI#4641 ·
メンテナーはふだん 1 日以内に返信