Comfy-Org/ComfyUI · error · ValueError

job id must be a UUID in canonical lowercase hyphenated form

Error message

job id must be a UUID in canonical lowercase hyphenated form

What it means

Raised by the job-id validator in comfy_execution/jobs.py when the id is a string but not a canonical lowercase-hyphenated UUID. The check is str(uuid.UUID(value)) == value, which rejects uppercase hex, braced forms ({...}), urn:uuid: prefixes, unhyphenated 32-char hex, and any garbage that uuid.UUID would parse-and-normalize differently. Canonical form is enforced because ids are matched verbatim in history, websocket, and /interrupt lookups.

Source

Thrown at comfy_execution/jobs.py:49

    ALL = [PENDING, IN_PROGRESS, COMPLETED, FAILED, CANCELLED]


def validate_job_id(value) -> str:
    """Validate a client-supplied job (prompt) id.

    Job ids must be UUIDs in the canonical lowercase hyphenated form. The id
    is stored and compared verbatim everywhere downstream — history keys,
    websocket events, and /interrupt matching — so accepting another spelling
    would silently rewrite the client's id and then miss every exact-match
    lookup. Rejecting loudly beats that.

    Returns the id unchanged. Raises ValueError when the value is not a
    string in canonical UUID form.
    """
    if not isinstance(value, str):
        raise ValueError(f"job id must be a string, got {type(value).__name__}")
    if str(uuid.UUID(value)) != value:
        raise ValueError("job id must be a UUID in canonical lowercase hyphenated form")
    return value


# Media types that can be previewed in the frontend
PREVIEWABLE_MEDIA_TYPES = frozenset({'images', 'video', 'audio', '3d', 'text'})

# 3D file extensions for preview fallback (no dedicated media_type exists)
THREE_D_EXTENSIONS = frozenset({'.obj', '.fbx', '.gltf', '.glb', '.usdz'})

# Text file extensions for preview fallback (the formats SaveText can produce)
TEXT_EXTENSIONS = frozenset({'.txt', '.md', '.json'})


def has_3d_extension(filename: str) -> bool:
    lower = filename.lower()
    return any(lower.endswith(ext) for ext in THREE_D_EXTENSIONS)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Generate ids as str(uuid.uuid4()) — already canonical lowercase hyphenated.
  2. Normalize existing ids client-side: str(uuid.UUID(raw)) before sending (only works if raw is parseable).
  3. Replace slug-style ids ('job-42') with per-request UUIDs and keep your own slug->uuid mapping.
  4. If upgrading a custom client across ComfyUI versions, audit every place a prompt id is produced or echoed.

Example fix

# before
prompt_id = uuid.uuid4().hex          # '0c9a...' no hyphens -> ValueError
prompt_id = str(uuid.uuid4()).upper() # uppercase -> ValueError

# after
prompt_id = str(uuid.uuid4())  # '0c9a586b-...' canonical form passes
Defensive patterns

Strategy: validation

Validate before calling

import uuid

def canonical_job_id(raw: str) -> str:
    return str(uuid.UUID(raw))  # raises if unparseable; output is canonical

prompt_id = canonical_job_id(prompt_id)  # safe to send

Type guard

def is_canonical_uuid(v) -> bool:
    if not isinstance(v, str): return False
    try: return str(uuid.UUID(v)) == v
    except ValueError: return False

Prevention

When it happens

Trigger: Posting /prompt with prompt_id='ABCDEF...' (uppercase), 'urn:uuid:...', '{...}', a 32-char hex without hyphens, or a random slug like 'my-job-1'. str(uuid.UUID(v)) normalizes all of these, so the equality check fails and the ValueError fires. Note uuid.UUID also raises its own ValueError on totally unparseable input, which surfaces with a different message.

Common situations: Clients using uuid.uuid4().hex (no hyphens) or str(uuid.uuid4()).upper(); ids copied from .NET or enterprise systems in braced/urn form; slugs from job queues reused as prompt ids; older ComfyUI versions that accepted arbitrary strings, breaking custom clients after the strictness change.

Related errors


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