Comfy-Org / Comfy-Org/ComfyUI-Manager

tqdm progress bar BrokenPipe silently discards completed generations in background/MCP mode

Open Beginner friendly
#3,223 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.1k
Forks
2.5k
Avg merge
5d 4h
Merged PRs (30d)
13

Description

# 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

1. Start ComfyUI in background so stderr has no live terminal:
```bash
nohup .venv/bin/python main.py --listen 127.0.0.1 --port 8188 > comfyui.log 2>&1 &
```
2. POST any prompt graph containing a `KSampler` to `http://127.0.0.1:8188/prompt`.
3. Poll `GET /history/`. 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//outputs`.
4. 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)

```python
# 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代為總結。

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in custom_nodes/ComfyUI-Manager/prestartup_script.py at the tqdm branch and trace how write_stderr and original_stderr.flush() handle progress output. Run the reported detached background/API reproduction, plus py_compile and the severed-pipe behavioural probe. Done means a BrokenPipeError from cosmetic progress output no longer marks the prompt as failed, and the completed generation returns success with its PNG saved.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.