langgenius/dify · warning · ValueError
must be a valid UUID
Error message
must be a valid UUID
What it means
Pydantic validation error 'must be a valid UUID', raised by the field_validator ChatMessagePayload.normalize_uuid on the conversation_id and parent_message_id fields (controllers/console/explore/completion.py:63-75). Blank/None values are accepted (returned as None). Any provided value is passed to libs.helper.uuid_value, which tries uuid.UUID(value); on failure it raises ValueError, which the validator re-raises as ValueError('must be a valid UUID'). Pydantic v2 converts this into a 422 Unprocessable Entity response before the handler runs.
Source
Thrown at api/controllers/console/explore/completion.py:75
query: str
files: list[dict[str, Any]] | None = Field(default=None)
conversation_id: str | None = None
parent_message_id: str | None = None
retriever_from: str = Field(default="explore_app")
@field_validator("conversation_id", "parent_message_id", mode="before")
@classmethod
def normalize_uuid(cls, value: str | UUID | None) -> str | None:
"""
Accept blank IDs and validate UUID format when provided.
"""
if not value:
return None
try:
return helper.uuid_value(value)
except ValueError as exc:
raise ValueError("must be a valid UUID") from exc
register_schema_models(console_ns, CompletionMessageExplorePayload, ChatMessagePayload)
register_response_schema_models(console_ns, SimpleResultResponse)
# define completion api for user
@console_ns.route(
"/installed-apps/<uuid:installed_app_id>/completion-messages",
endpoint="installed_app_completion",
)
class CompletionApi(InstalledAppResource):
@console_ns.expect(console_ns.models[CompletionMessageExplorePayload.__name__])
@console_ns.response(200, "Success")
@with_current_user
@with_session
@model_validate(CompletionMessageExplorePayload)
def post(View on GitHub (pinned to ef8544b173)
Solutions
- Only pass a canonical UUID v4 string (or None/empty) for conversation_id and parent_message_id.
- If you hold a non-UUID identifier, resolve it to the Dify UUID before calling, or omit the field to start a new conversation.
- Validate the value client-side with a UUID regex before posting.
- Ensure the value is not undefined/NaN serialized as the literal string 'undefined'.
Example fix
// before body.conversation_id = chatSession.nanoid; // e.g. 'V1StGXR8_Z5j' -> 422 // after: resolve to the Dify UUID, or omit for a new conversation body.conversation_id = chatSession.difyUuid; // '550e8400-e29b-41d4-a716-446655440000' // or delete body.conversation_id; // start a new conversation
Defensive patterns
Strategy: validation
Validate before calling
import { v4 as uuidv4, validate as uuidValidate } from "uuid"
function normalizeId(value: string | null | undefined): string | null {
if (!value) return null
if (!uuidValidate(value)) throw new Error(`conversation_id must be a UUID, got ${value}`)
return value
}
// before POST:
body.conversation_id = normalizeId(body.conversation_id)
body.parent_message_id = normalizeId(body.parent_message_id) Type guard
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
function isUuid(value: unknown): value is string {
return typeof value === "string" && UUID_RE.test(value)
} Try / catch
try { await postChat(body) }
catch (e) {
if (e.status === 422 && /must be a valid UUID/.test(e.message))
showFieldError('conversation_id or parent_message_id must be a UUID or blank')
else throw e
} Prevention
- Only pass canonical UUID strings (or null/empty) for conversation_id and parent_message_id.
- Validate with a UUID regex client-side before posting.
- Never send internal/nanoid identifiers in these fields; map them to the Dify UUID first, or omit to start a new conversation.
- Guard against the literal string 'undefined' being serialized from the frontend.
When it happens
Trigger: POST to a chat-message endpoint that uses ChatMessagePayload (e.g. installed-app chat messages) with conversation_id or parent_message_id set to a non-UUID string such as 'abc', '123', a nanoid, an integer, or a malformed UUID like '550e8400-e29b-41d4-a716'. Blank strings and None are allowed and normalize to None.
Common situations: Client sends an internal/non-UUID id format (e.g., a sortable/nanoid from another system); copy-paste truncation of a UUID; frontend passes an empty-string sentinel that is not actually empty after trimming of surrounding characters (a truly empty string is fine); version mismatch where an older API accepted arbitrary strings.
Related errors
- Invalid UUID format in tag_ids.
- Invalid UUID format in creator_ids.
- usage_invalid_flag
- KNOWLEDGE_FS_BASE_URL must be an absolute HTTP(S) URL
- NEW_USER_DEFAULT_MODELS entries must use 'model_type:provide
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/a6c267e907592ee7.
Report an issue: GitHub.