cocoindex-io/cocoindex · error · ValueError
Invalid Qdrant point ID {raw!r}: strings must be UUIDs. {_PO
Error message
Invalid Qdrant point ID {raw!r}: strings must be UUIDs. {_POINT_ID_RULE} What it means
Qdrant accepts string point IDs only when they are valid UUIDs. declare_point attempts uuid.UUID(raw) on every string ID and raises this ValueError (with the point-ID rule text) for anything that is not a UUID in a form Python's uuid can parse. This fails at declare time rather than with an opaque Qdrant transport error at upsert.
Source
Thrown at python/cocoindex/connectors/qdrant/_target.py:758
Qdrant only accepts unsigned 64-bit integers and UUIDs (any textual
form: hyphenated, 32-char hex, or URN); everything else is rejected at
upsert time with an opaque transport error, so fail at declare time
with an actionable one instead.
"""
if isinstance(raw, int):
if not 0 <= raw < 1 << 64:
raise ValueError(
f"Invalid Qdrant point ID {raw!r}: out of unsigned 64-bit range. "
f"{_POINT_ID_RULE}"
)
return raw
if isinstance(raw, uuid.UUID):
return str(raw)
if isinstance(raw, str):
try:
uuid.UUID(raw)
except ValueError:
raise ValueError(
f"Invalid Qdrant point ID {raw!r}: strings must be UUIDs. "
f"{_POINT_ID_RULE}"
) from None
return raw
raise ValueError(
f"Invalid Qdrant point ID of type {type(raw).__name__}. {_POINT_ID_RULE}"
)
__all__ = [
"CollectionSchema",
"CollectionTarget",
"PointStruct",
"QdrantSparseVectorDef",
"QdrantVectorDef",
"collection_target",
"create_client",
"declare_collection_target",View on GitHub (pinned to e84aa99b32)
Solutions
- Convert the key to a UUID: str(uuid.uuid5(uuid.NAMESPACE_URL, f"doc/{key}")) for a stable, deterministic ID.
- If you have a numeric ID, pass it as a Python int (in [0, 2^64)) instead of a string.
- Validate with `str(uuid.UUID(s))` before declaring if the string is supposed to be a UUID.
- Prepend the accepted prefix (urn:uuid: or braces) is fine only if the rest is a valid UUID — otherwise regenerate.
Example fix
// before await target.declare_point(id="doc-123", ...) // after import uuid await target.declare_point(id=str(uuid.uuid5(uuid.NAMESPACE_URL, "doc/doc-123")), ...)
Defensive patterns
Strategy: validation
Validate before calling
import uuid
def _ensure_uuid_str(s):
uuid.UUID(s) # raises if not a UUID
return s Type guard
def is_uuid_string(s):
if not isinstance(s, str): return False
try: uuid.UUID(s); return True
except ValueError: return False Try / catch
try:
await target.declare_point(id=pid, ...)
except ValueError as e:
pid = str(uuid.uuid5(uuid.NAMESPACE_URL, f"doc/{raw_key}"))
await target.declare_point(id=pid, ...) Prevention
- Derive point IDs from natural keys via uuid.uuid5 instead of using raw strings.
- Pass numeric IDs as ints, not strings.
- Add an is_uuid_string check in your declare wrapper.
When it happens
Trigger: Calling declare_point with a string point ID like "doc-123", "my/file.md", a numeric string "42", or any non-UUID string; also UUID-ish strings with invalid formatting (wrong length/characters).
Common situations: Passing file paths or natural keys directly as point IDs; storing integer IDs as strings; truncated or malformed UUIDs copied from logs.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid Qdrant point ID {raw!r}: out of unsigned 64-bit rang
- Invalid Qdrant point ID of type {type(raw).__name__}. {_POIN
- qdrant-client is required to use the Qdrant connector. Pleas
- Invalid vector definition: {vector_def}
- Qdrant sparse vectors are always named; pass them in a dict,
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/fe7b97b8682d635f.
Report an issue: GitHub.