{"record":{"id":"ef9c54f68a4ee24a","repo":"Comfy-Org/ComfyUI","slug":"invalid-body-ef9c54","errorCode":"INVALID_BODY","errorMessage":"uploads require exactly one destination role: input, models, or output","messagePattern":"uploads require exactly one destination role: input, models, or output","errorType":"http","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"app/assets/services/path_utils.py","lineNumber":40,"sourceCode":"    targets: list[tuple[str, list[str], set[str]]] = []\n    for name, values in folder_paths.folder_names_and_paths.items():\n        if name in _NON_MODEL_FOLDER_NAMES:\n            continue\n        paths, exts = values[0], values[1]\n        if paths:\n            targets.append((name, paths, set(exts)))\n    return targets\n\n\ndef resolve_destination_from_tags(tags: list[str]) -> tuple[str, list[str]]:\n    \"\"\"Validates and maps upload routing tags -> (base_dir, subdirs_for_fs).\n\n    The request tags are only used to choose the write destination. Extra tags\n    remain labels; they do not become path components or trusted classification.\n    \"\"\"\n    destination_roles = [t for t in tags if t in {\"input\", \"models\", \"output\"}]\n    if len(destination_roles) != 1:\n        raise ValueError(\"uploads require exactly one destination role: input, models, or output\")\n\n    root = destination_roles[0]\n    if root == \"models\":\n        model_type_tags = [t for t in tags if t.startswith(\"model_type:\")]\n        if len(model_type_tags) != 1:\n            raise ValueError(\"models uploads require exactly one model_type:<folder_name> tag\")\n        folder_name = model_type_tags[0].split(\":\", 1)[1]\n        if not folder_name:\n            raise ValueError(\"models uploads require exactly one model_type:<folder_name> tag\")\n        model_folder_paths = {\n            name: paths for name, paths, _exts in get_comfy_models_folders()\n        }\n        try:\n            bases = model_folder_paths[folder_name]\n        except KeyError:\n            raise ValueError(f\"unknown model category '{folder_name}'\")\n        if not bases:\n            raise ValueError(f\"no base path configured for category '{folder_name}'\")","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/app/assets/services/path_utils.py#L22-L58","documentation":"Raised by resolve_destination_from_tags when the tag list does not contain exactly one destination role from {'input','models','output'}. Tags are the only routing signal for upload destinations: zero roles means the server cannot pick a base directory, two or more are ambiguous. ValueError here surfaces to the caller as INVALID_BODY.","triggerScenarios":"POST an upload with tags=['user:alice'] (no role), or tags=['input','output'] (two roles). Both fail the len(destination_roles) != 1 check.","commonSituations":"Clients that send freeform/label tags only; UI that lets users multi-select destinations; copy-paste of example tag lists that include several roles; legacy clients hardcoding 'output' while the server adds 'input'.","solutions":["Send exactly one of 'input', 'models', or 'output' in the tags array, plus any extra label tags you want.","Validate the tag list client-side before upload: exactly one role, and for 'models' exactly one model_type:<folder> tag.","If your workflow needs bytes in two destinations, perform two uploads (or a copy operation), not one multi-role upload."],"exampleFix":"# before\ntags = ['input', 'output', 'my-label']\n\n# after\ntags = ['input', 'my-label']","handlingStrategy":"validation","validationCode":"ROLES = {'input', 'models', 'output'}\ndef valid_upload_tags(tags: list[str]) -> bool:\n    roles = [t for t in tags if t in ROLES]\n    if len(roles) != 1:\n        return False\n    if roles[0] == 'models':\n        mt = [t for t in tags if t.startswith('model_type:')]\n        if len(mt) != 1 or not mt[0].split(':', 1)[1]:\n            return False\n    return True","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Exactly one role tag per upload; treat it as a required form field","For 'models', add exactly one non-empty model_type:<folder> tag","Run the same count checks client-side that the server performs"],"tags":["upload","tags","destination","validation"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}