MemPalace/mempalace · error · ValueError
update requires at least one of documents, metadatas, embedd
Error message
update requires at least one of documents, metadatas, embeddings
What it means
Raised by QdrantCollection.update() when documents, metadatas and embeddings are all None. update() performs a read-merge-write; with nothing to merge it would be a no-op that still round-trips to the server, so the API requires at least one field to change.
Source
Thrown at mempalace/backends/qdrant.py:861
for doc_id, doc, meta, vector in zip(ids, documents, metadatas, vectors):
points.append(
{
"id": _point_id(doc_id),
"vector": vector,
"payload": {
_PAYLOAD_ID: str(doc_id),
_PAYLOAD_DOCUMENT: str(doc),
_PAYLOAD_METADATA: _jsonable_metadata(meta),
"updated_at": _utcnow(),
},
}
)
self._client.upsert_points(self._remote_collection, points)
self._backend._write_marker(self._palace, self._config)
def update(self, *, ids, documents=None, metadatas=None, embeddings=None):
if documents is None and metadatas is None and embeddings is None:
raise ValueError("update requires at least one of documents, metadatas, embeddings")
n = len(ids)
for label, value in (
("documents", documents),
("metadatas", metadatas),
("embeddings", embeddings),
):
if value is not None and len(value) != n:
raise ValueError(f"{label} length {len(value)} does not match ids length {n}")
existing = self.get(ids=ids, include=["documents", "metadatas", "embeddings"])
by_id = {
rid: (existing.documents[i], existing.metadatas[i], existing.embeddings[i])
for i, rid in enumerate(existing.ids)
if existing.embeddings is not None
}
out_ids = []
out_docs = []
out_metas = []
out_embeddings = []View on GitHub (pinned to 06cb6987f0)
Solutions
- Guard before calling: if documents is metadatas is embeddings is None: return (nothing to update)
- If the intent was deletion, call delete() instead
- If the intent was a no-op touch of updated_at, do it explicitly with metadatas (merge same metadata)
- Audit the caller building the kwargs dict — usually an empty patch should be short-circuited earlier
Example fix
# before
updates = {k: v for k, v in patch.items() if k in ("documents","metadatas","embeddings")}
collection.update(ids=ids, **updates) # empty patch -> ValueError
// after
if not any(updates.get(k) is not None for k in ("documents","metadatas","embeddings")):
return # nothing to update
collection.update(ids=ids, **updates) Defensive patterns
Strategy: validation
Validate before calling
if documents is None and metadatas is None and embeddings is None:
return # nothing to update Prevention
- Short-circuit empty patches in your update layer before touching the backend
- Build update kwargs explicitly rather than forwarding possibly-empty dicts
When it happens
Trigger: Calling update(ids=my_ids) with no other kwargs — often from generic code that builds kwargs dynamically and ends up with all-None values (e.g. an update dict where every optional field was absent).
Common situations: A generic CRUD layer forwarding user input where all optional fields were omitted; a partial-update helper that receives an empty patch dict; conditional code paths that compute new values but a branch leaves everything None.
Related errors
- add ids must be unique
- {label} length {len(value)} does not match ids length {n}
- query requires query_embeddings
- Embedding model mismatch reading palace at {palace_path!r}.
- delete requires either ids= or where=
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/d64524dae4933ff2.
Report an issue: GitHub.