{"record":{"id":"52dcab67b87fa25f","repo":"Comfy-Org/ComfyUI","slug":"job-id-must-be-a-uuid-in-canonical-lowercase-hyphe","errorCode":null,"errorMessage":"job id must be a UUID in canonical lowercase hyphenated form","messagePattern":"job id must be a UUID in canonical lowercase hyphenated form","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_execution/jobs.py","lineNumber":49,"sourceCode":"    ALL = [PENDING, IN_PROGRESS, COMPLETED, FAILED, CANCELLED]\n\n\ndef validate_job_id(value) -> str:\n    \"\"\"Validate a client-supplied job (prompt) id.\n\n    Job ids must be UUIDs in the canonical lowercase hyphenated form. The id\n    is stored and compared verbatim everywhere downstream — history keys,\n    websocket events, and /interrupt matching — so accepting another spelling\n    would silently rewrite the client's id and then miss every exact-match\n    lookup. Rejecting loudly beats that.\n\n    Returns the id unchanged. Raises ValueError when the value is not a\n    string in canonical UUID form.\n    \"\"\"\n    if not isinstance(value, str):\n        raise ValueError(f\"job id must be a string, got {type(value).__name__}\")\n    if str(uuid.UUID(value)) != value:\n        raise ValueError(\"job id must be a UUID in canonical lowercase hyphenated form\")\n    return value\n\n\n# Media types that can be previewed in the frontend\nPREVIEWABLE_MEDIA_TYPES = frozenset({'images', 'video', 'audio', '3d', 'text'})\n\n# 3D file extensions for preview fallback (no dedicated media_type exists)\nTHREE_D_EXTENSIONS = frozenset({'.obj', '.fbx', '.gltf', '.glb', '.usdz'})\n\n# Text file extensions for preview fallback (the formats SaveText can produce)\nTEXT_EXTENSIONS = frozenset({'.txt', '.md', '.json'})\n\n\ndef has_3d_extension(filename: str) -> bool:\n    lower = filename.lower()\n    return any(lower.endswith(ext) for ext in THREE_D_EXTENSIONS)\n\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_execution/jobs.py#L31-L67","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Generate ids as str(uuid.uuid4()) — already canonical lowercase hyphenated.","Normalize existing ids client-side: str(uuid.UUID(raw)) before sending (only works if raw is parseable).","Replace slug-style ids ('job-42') with per-request UUIDs and keep your own slug->uuid mapping.","If upgrading a custom client across ComfyUI versions, audit every place a prompt id is produced or echoed."],"exampleFix":"# before\nprompt_id = uuid.uuid4().hex          # '0c9a...' no hyphens -> ValueError\nprompt_id = str(uuid.uuid4()).upper() # uppercase -> ValueError\n\n# after\nprompt_id = str(uuid.uuid4())  # '0c9a586b-...' canonical form passes","handlingStrategy":"validation","validationCode":"import uuid\n\ndef canonical_job_id(raw: str) -> str:\n    return str(uuid.UUID(raw))  # raises if unparseable; output is canonical\n\nprompt_id = canonical_job_id(prompt_id)  # safe to send","typeGuard":"def is_canonical_uuid(v) -> bool:\n    if not isinstance(v, str): return False\n    try: return str(uuid.UUID(v)) == v\n    except ValueError: return False","tryCatchPattern":null,"preventionTips":["Generate ids with str(uuid.uuid4()) — already canonical.","Never use .hex, .upper(), braces, or urn: prefixes.","Normalize arbitrary UUID spellings with str(uuid.UUID(raw)) before sending."],"tags":["api","jobs","validation","uuid"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}