Comfy-Org/ComfyUI · error · UploadError

INVALID_HASH

INVALID_HASH

Error message

hash must be like 'blake3:<hex>'

What it means

Raised from the HTTP >=400 branch (comfy_api_nodes/util/client.py:823) via _friendly_http_message for status 429: 'Rate Limit Exceeded: The server returned 429 after all retry attempts. Please wait and try again.' The client already honors Retry-After and re-attempts rate-limited requests (max_retries_on_rate_limit); this error means even those retries kept hitting 429.

Source

Thrown at app/assets/api/upload.py:21

import uuid
from typing import Callable

from aiohttp import web

import folder_paths
from app.assets.api.schemas_in import ParsedUpload, UploadError
from app.assets.helpers import validate_blake3_hash


def normalize_and_validate_hash(s: str) -> str:
    """Validate and normalize a hash string.

    Returns canonical 'blake3:<hex>' or raises UploadError.
    """
    try:
        return validate_blake3_hash(s)
    except ValueError:
        raise UploadError(400, "INVALID_HASH", "hash must be like 'blake3:<hex>'")


async def parse_multipart_upload(
    request: web.Request,
    check_hash_exists: Callable[[str], bool],
) -> ParsedUpload:
    """
    Parse a multipart/form-data upload request.

    Args:
        request: The aiohttp request
        check_hash_exists: Callable(hash_str) -> bool to check if a hash exists

    Returns:
        ParsedUpload with parsed fields and temp file path

    Raises:
        UploadError: On validation or I/O errors

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Wait for the limit window to reset, then retry with fewer concurrent API nodes
  2. Reduce workflow parallelism (fewer simultaneous API-account nodes) or space submissions with a delay
  3. Increase max_retries_on_rate_limit / retry_backoff so the client's built-in backoff covers the provider's window
  4. Check the response headers in the request log for Retry-After and pace accordingly

Example fix

// before
await sync_op_raw(cls, endpoint, max_retries_on_rate_limit=2, retry_backoff=1.5)

// after
await sync_op_raw(cls, endpoint, max_retries_on_rate_limit=6, retry_backoff=3.0)
Defensive patterns

Strategy: retry

Validate before calling

# pace submissions below the provider's limit
async def bounded(nodes, coros, limit=2, gap=1.0):
    sem = asyncio.Semaphore(limit)
    async def run(c):
        async with sem:
            await asyncio.sleep(gap)
            return await c
    return await asyncio.gather(*(run(c) for c in coros))

Try / catch

try:
    result = await sync_op(...)
except Exception as e:
    if "Rate Limit Exceeded" in str(e):
        await asyncio.sleep(retry_after_from_log or 60)
        result = await sync_op(...)
    else:
        raise

Prevention

When it happens

Trigger: Firing many API nodes in rapid succession (parallel queued workflows); a single account shared by multiple machines; retry storms where backoff windows are shorter than the provider's limit window; provider-side throttling during peak load.

Common situations: Batch runs with high fan-out; automation scripts without pacing; multiple users on one API key; provider rate-limit tier too low for the workload.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/d3ec5e9ca9bc2f14. Report an issue: GitHub.