Skip to content

comfyui: disconnect() permanently disables WebSocket reconnection on reused clients #801

@willgriffin

Description

@willgriffin

Bug

ComfyUIClient.disconnect() sets this.options.reconnect.enabled = false, which permanently disables WebSocket reconnection for the lifetime of the client instance. When the client is cached and reused across multiple operations (as histrio does via getComfyClient()), this means:

  1. First generation: WebSocket connects, runs, disconnect() called in finally block → reconnect.enabled = false
  2. Second generation: Same client instance, connect() creates new WebSocket. If it drops mid-operation, handleDisconnect() checks reconnect.enabledfalse → no reconnection
  3. The built-in reconnection logic (5 attempts, 1s delay) becomes dead code after the first disconnect() call

Impact

Long-running ComfyUI workflows (e.g., Wan 2.2 I2V with 81 frames, 10-15 min total) are vulnerable to WebSocket drops through reverse proxies. Without reconnection, waitForCompletion falls back to HTTP polling, which works but loses real-time progress events. If the WebSocket connection fails entirely on connect(), the pipeline crashes unless the caller wraps it in try/catch.

Location

packages/comfyui/src/client.ts:281

async disconnect(): Promise<void> {
    this.options.reconnect.enabled = false; // ← bug: permanently mutates shared options
    this.messageHandlers.clear();
    // ...
}

Suggested Fix

disconnect() should close the WebSocket and clear handlers without permanently disabling reconnection:

async disconnect(): Promise<void> {
    this.messageHandlers.clear();
    if (this.ws) {
        this.ws.close();
        this.ws = null;
    }
}

If callers need to prevent reconnection during shutdown, that should be explicit (e.g., client.destroy() or a separate flag).

Workaround

Callers can wrap connect() in try/catch and rely on HTTP polling via waitForCompletion's built-in fallback. This is what histrio currently does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumMedium priority (default)size: mMedium (4-8 hours)type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions