MemPalace/mempalace · error · ValueError
qdrant requires explicit embeddings
Error message
qdrant requires explicit embeddings
What it means
Raised by QdrantCollection.add() when embeddings is None. Unlike the ChromaDB default backend (which can embed internally), this minimal Qdrant REST backend has no built-in embedder, so callers must supply vectors explicitly. The message points users to the palace.get_collection wrapper, which injects the configured local embedder.
Source
Thrown at mempalace/backends/qdrant.py:822
rows = self._scroll_all(qdrant_filter=q_filter, with_vector=with_vector)
rows = [
row
for row in rows
if (ids is None or row["id"] in set(ids))
and _matches_where(row["metadata"], where)
and _matches_where_document(row["document"], where_document)
]
return rows
def add(self, *, documents, ids, metadatas=None, embeddings=None):
_validate_write_batch(
documents=documents,
ids=ids,
metadatas=metadatas,
embeddings=embeddings,
)
if embeddings is None:
raise ValueError("qdrant requires explicit embeddings")
if len(set(ids)) != len(ids):
raise ValueError("add ids must be unique")
existing = self.get(ids=list(ids), include=[])
if existing.ids:
raise ValueError(f"ids already exist in qdrant collection: {existing.ids}")
self.upsert(documents=documents, ids=ids, metadatas=metadatas, embeddings=embeddings)
def upsert(self, *, documents, ids, metadatas=None, embeddings=None):
_validate_write_batch(
documents=documents,
ids=ids,
metadatas=metadatas,
embeddings=embeddings,
)
if embeddings is None:
raise ValueError("qdrant requires explicit embeddings")
vectors, dimension = _normalize_vectors(embeddings)
self._ensure_remote_collection(dimension)View on GitHub (pinned to 06cb6987f0)
Solutions
- Use palace.get_collection(...) which wraps add() and computes embeddings via the configured local model
- Or pass embeddings explicitly: embeddings=[embed(d) for d in documents]
- Verify the configured embedder (Ollama/LM Studio) actually loads and returns vectors — a None return upstream becomes this error
- Check the backend docs: this backend deliberately delegates embedding to the caller (local-first design)
Example fix
# before
collection.add(documents=docs, ids=ids) # ValueError: qdrant requires explicit embeddings
# after
from mempalace.palace import get_collection # wrapper injects embedder
collection = palace.get_collection("notes")
collection.add(documents=docs, ids=ids) Defensive patterns
Strategy: validation
Validate before calling
if embeddings is None:
embeddings = [embedder.embed(d) for d in documents] # compute before calling add() Prevention
- Always obtain collections via palace.get_collection so embedding is injected
- Never port Chroma-style add(documents=...) calls verbatim to this backend
- Centralize writes through one wrapper function that always supplies embeddings
When it happens
Trigger: Calling raw collection.add(documents=..., ids=...) with no embeddings, the way you would with default Chroma. Also if a wrapper that normally computes embeddings passes embeddings=None through.
Common situations: Porting code from the Chroma backend to Qdrant; using a raw collection handle from backend.get_collection() instead of palace.get_collection(); the wrapper's embedder returned None due to a model-load failure.
Related errors
- qdrant requires query_embeddings; use palace.get_collection
- pgvector requires query_embeddings; use palace.get_collectio
- embeddings length {len(embeddings)} does not match ids lengt
- embedding must be a non-empty 1D vector
- qdrant batch cannot mix embedding dimensions {sorted(dims)}
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/df542b38897378dc.
Report an issue: GitHub.