BrokenPipe — tqdm progress bar kills valid generations in background + MCP/API mode
Suggested issue for: Comfy-Org/ComfyUI-Manager
(bug lives in prestartup_script.py of the Manager custom node, not ComfyUI core)
Summary
When ComfyUI is launched in background / non-interactive mode (which is how the
official MCP + API / agent-driven usage is meant to run) and you submit a prompt that
contains a KSampler, the generation actually completes, but the tqdm progress-bar
renderer writes to a severed stderr pipe during sampling, raises BrokenPipeError, and
that exception propagates up the execution chain — flagging the whole prompt as
status_str: "error". The finished image is never saved. A fully valid generation is
silently discarded because the display layer crashed.
Environment
- ComfyUI:
0.34.0 (WSL2 / Linux)
- ComfyUI-Manager: latest (
d47c9346 "update DB") — bug present at HEAD
- Launch mode: detached background
python main.py --listen 127.0.0.1 --port 8188 (stderr redirected to a closed pipe)
- Client: REST
/prompt (same occurs via comfy MCP; both go through the same API)
Reproduce
- Start ComfyUI in background so stderr has no live terminal:
nohup .venv/bin/python main.py --listen 127.0.0.1 --port 8188 > comfyui.log 2>&1 &
- POST any prompt graph containing a
KSampler to http://127.0.0.1:8188/prompt.
- Poll
GET /history/<prompt_id>. Observe:
status_str: "error"
exception_type: BrokenPipeError
exception_message: "[Errno 32] Broken pipe"
executed: ["70", "86", "22", "45", "17", "1", "42"] # KSampler ran, all deps ran
and no output image in /history/<id>/outputs.
- Note the server log actually reports the sampling finished:
Prompt executed in 5.83 seconds
Root cause
The traceback funnels through:
k_diffusion/sampling.py res_multistep()
→ tqdm progress bar (trange)
→ tqdm/std.py display() → print_status() → fp.write()
→ custom_nodes/ComfyUI-Manager/prestartup_script.py
write_stderr(message)
original_stderr.flush() # ← BrokenPipeError here
ComfyUI-Manager's prestartup_script.py installs a stream wrapper that re-emits tqdm
progress to original_stderr. In background/detached mode the stderr pipe's read end has
already been closed, so each progress-bar refresh raises BrokenPipeError. Because this
happens inside the sampler loop, the exception is not contained — it bubbles all the way
up and marks the entire job failed, even though sampling succeeded.
Why this matters (official direction)
Background + MCP/API is the officially promoted way to drive ComfyUI (agents, automation,
headless servers). In that mode stderr is commonly redirected, so every KSampler job is
at risk of this. It is not an exotic one-off.
Suggested fix (minimal, display-only)
# custom_nodes/ComfyUI-Manager/prestartup_script.py (tqdm branch)
if '100%' in message:
self.sync_write(message)
else:
try:
write_stderr(message)
original_stderr.flush()
except (BrokenPipeError, OSError):
pass # progress-bar output is cosmetic; never fail the job because of it
- Touches only the display path. Does not alter sampling, output, or error handling.
- The progress bar is cosmetic; a broken pipe on it should never abort a completed generation.
Workaround (no code change)
Launch with stderr pointed at a real file/terminal, or ignore the error server-side —
but the honest fix is the two-line guard above, so completed generations are not dropped.
Filed from a background-launched, MCP-driven ComfyUI instance; patch verified locally
(ad-hoc py_compile + severed-pipe behavioural probe pass; generation returns success and
saves PNG after applying the guard).
以上內容是由Agent代為總結。
BrokenPipe — tqdm progress bar kills valid generations in background + MCP/API mode
Summary
When ComfyUI is launched in background / non-interactive mode (which is how the
official MCP + API / agent-driven usage is meant to run) and you submit a prompt that
contains a
KSampler, the generation actually completes, but the tqdm progress-barrenderer writes to a severed stderr pipe during sampling, raises
BrokenPipeError, andthat exception propagates up the execution chain — flagging the whole prompt as
status_str: "error". The finished image is never saved. A fully valid generation issilently discarded because the display layer crashed.
Environment
0.34.0(WSL2 / Linux)d47c9346 "update DB") — bug present at HEADpython main.py --listen 127.0.0.1 --port 8188(stderr redirected to a closed pipe)/prompt(same occurs via comfy MCP; both go through the same API)Reproduce
KSamplertohttp://127.0.0.1:8188/prompt.GET /history/<prompt_id>. Observe:/history/<id>/outputs.Prompt executed in 5.83 secondsRoot cause
The traceback funnels through:
ComfyUI-Manager's
prestartup_script.pyinstalls a stream wrapper that re-emits tqdmprogress to
original_stderr. In background/detached mode the stderr pipe's read end hasalready been closed, so each progress-bar refresh raises
BrokenPipeError. Because thishappens inside the sampler loop, the exception is not contained — it bubbles all the way
up and marks the entire job failed, even though sampling succeeded.
Why this matters (official direction)
Background + MCP/API is the officially promoted way to drive ComfyUI (agents, automation,
headless servers). In that mode stderr is commonly redirected, so every KSampler job is
at risk of this. It is not an exotic one-off.
Suggested fix (minimal, display-only)
Workaround (no code change)
Launch with stderr pointed at a real file/terminal, or ignore the error server-side —
but the honest fix is the two-line guard above, so completed generations are not dropped.
Filed from a background-launched, MCP-driven ComfyUI instance; patch verified locally
(ad-hoc py_compile + severed-pipe behavioural probe pass; generation returns
successandsaves PNG after applying the guard).
以上內容是由Agent代為總結。