Comfy-Org/ComfyUI · error · ValueError

INVALID_BODY

INVALID_BODY

Error message

Unknown tags: {missing}

What it means

ValueError raised by validate_tags_exist when any requested tag names are absent from the Tag table. It queries Tag.name IN (tags) and reports every missing name in the message, so the error doubles as a report of exactly which tags need creating.

Source

Thrown at app/assets/database/queries/tags.py:55

    total_tags: list[str]


@dataclass(frozen=True)
class SetTagsResult:
    added: list[str]
    removed: list[str]
    total: list[str]


def validate_tags_exist(session: Session, tags: list[str]) -> None:
    """Raise ValueError if any of the given tag names do not exist."""
    existing_tag_names = set(
        name
        for (name,) in session.execute(select(Tag.name).where(Tag.name.in_(tags))).all()
    )
    missing = [t for t in tags if t not in existing_tag_names]
    if missing:
        raise ValueError(f"Unknown tags: {missing}")


def ensure_tags_exist(session: Session, names: Iterable[str]) -> None:
    wanted = normalize_tags(list(names))
    if not wanted:
        return
    rows = [{"name": n} for n in list(dict.fromkeys(wanted))]
    ins = (
        sqlite.insert(Tag)
        .values(rows)
        .on_conflict_do_nothing(index_elements=[Tag.name])
    )
    session.execute(ins)


def get_reference_tags(session: Session, reference_id: str) -> list[str]:
    return [
        tag_name

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Create the tags first with ensure_tags_exist (or pass create_if_missing=True in add_tags_to_reference).
  2. Normalize tag names the same way the writers do (strip + case handling per normalize_tags) before validating.
  3. Parse the missing list from the error message and offer tag creation to the user.
  4. Map this ValueError to 400 INVALID_BODY at the API boundary since it indicates a bad request payload.

Example fix

// before
add_tags_to_reference(session, rid, ["ink", "sketch "], create_if_missing=False)

// after
from app.assets.database.queries.tags import ensure_tags_exist
wanted = normalize_tags(["ink", "sketch "])
ensure_tags_exist(session, wanted)
add_tags_to_reference(session, rid, wanted, create_if_missing=False)
Defensive patterns

Strategy: validation

Validate before calling

from app.assets.database.queries.tags import normalize_tags

def tags_are_known(session, tags: list[str]) -> bool:
    wanted = normalize_tags(tags)
    existing = {n for (n,) in session.execute(select(Tag.name).where(Tag.name.in_(wanted))).all()}
    return set(wanted) <= existing

Try / catch

try:
    add_tags_to_reference(session, rid, tags, create_if_missing=False)
except ValueError as e:
    # message lists the missing names; map to 400 INVALID_BODY
    raise HTTPException(status_code=400, detail=str(e))

Prevention

When it happens

Trigger: Calling add_tags_to_reference (or any tag path) with create_if_missing=False after the tags were never created, or with names that normalize differently than how they were stored (case/whitespace). Also triggered by direct validate_tags_exist calls in API request validation.

Common situations: Clients sending free-form tag strings to an endpoint that requires pre-existing tags; tags created in one environment and expected in another; whitespace or case variants ('Sketch ' vs 'sketch') that miss the stored name because normalization differs between write and validate paths.

Related errors


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