{"record":{"id":"564cf1f1cf30218b","repo":"langgenius/dify","slug":"invalid-uuid-format-in-tag-ids","errorCode":null,"errorMessage":"Invalid UUID format in tag_ids.","messagePattern":"Invalid UUID format in tag_ids\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"api/controllers/console/app/app.py","lineNumber":122,"sourceCode":"    is_created_by_me: bool | None = Field(default=None, description=\"Filter by creator\")\n\n    @field_validator(\"tag_ids\", mode=\"before\")\n    @classmethod\n    def validate_tag_ids(cls, value: list[str] | None) -> list[str] | None:\n        if not value:\n            return None\n\n        if not isinstance(value, list):\n            raise ValueError(\"Unsupported tag_ids type.\")\n\n        items = [str(item).strip() for item in value if item and str(item).strip()]\n        if not items:\n            return None\n\n        try:\n            return [str(uuid.UUID(item)) for item in items]\n        except ValueError as exc:\n            raise ValueError(\"Invalid UUID format in tag_ids.\") from exc\n\n    @field_validator(\"creator_ids\", mode=\"before\")\n    @classmethod\n    def validate_creator_ids(cls, value: list[str] | None) -> list[str] | None:\n        if not value:\n            return None\n\n        if not isinstance(value, list):\n            raise ValueError(\"Unsupported creator_ids type.\")\n\n        items = [str(item).strip() for item in value if item and str(item).strip()]\n        if not items:\n            return None\n\n        try:\n            return [str(uuid.UUID(item)) for item in items]\n        except ValueError as exc:\n            raise ValueError(\"Invalid UUID format in creator_ids.\") from exc","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/app/app.py#L104-L140","documentation":"Raised by AppListBaseQuery.validate_tag_ids when at least one stripped item fails uuid.UUID() construction. The validator normalizes every item to a stringified UUID; any malformed value re-raises as 'Invalid UUID format in tag_ids.' inside a Pydantic ValidationError.","triggerScenarios":"Passing a non-UUID string in tag_ids (slug, integer, name, partial UUID, UUID with wrong hyphenation). Common with copy-paste of tag slugs instead of tag IDs.","commonSituations":"Frontend stores tag names instead of tag IDs; URL-encoding mangles the UUID; partial UUID copied from the UI; tag IDs from a different environment that uses different identifiers.","solutions":["Use the full canonical UUID (e.g., 550e8400-e29b-41d4-a716-446655440000) returned by the tag list endpoint.","Fetch valid tag IDs first via GET /console/apps/tags and select from those.","Strip whitespace and verify format client-side before sending.","Reject empty or partial strings in the UI before submit."],"exampleFix":"// before\nconst ids = tags.map(t => t.name);\n\n// after\nconst ids = tags.map(t => t.id); // full UUID from GET /apps/tags","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction filterValidUuids(ids) { return (ids || []).filter((id) => UUID_RE.test(id)); }","typeGuard":"const isUuid = (v) => typeof v === 'string' && UUID_RE.test(v);","tryCatchPattern":"try { await axios.get('/apps', { params }); }\ncatch (e) { if (/Invalid UUID format in tag_ids/.test(e.message)) params.tag_ids = filterValidUuids(params.tag_ids); }","preventionTips":["Source tag IDs only from GET /apps/tags.","Strip and UUID-validate each ID client-side before sending.","Reject partial UUIDs in the UI."],"tags":["apps","pydantic","uuid","query-params","validation","console-api"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}