MemPalace/mempalace · error · ValueError
{label} length {len(value)} does not match ids length {n}
Error message
{label} length {len(value)} does not match ids length {n} What it means
Raised by QdrantCollection.update() when any of the provided parallel arrays (documents, metadatas, embeddings) has a length different from the ids array. update() merges per-id, so every supplied array must align 1:1 with ids.
Source
Thrown at mempalace/backends/qdrant.py:869
_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 = []
for idx, doc_id in enumerate(ids):
if doc_id not in by_id:
continue
prev_doc, prev_meta, prev_embedding = by_id[doc_id]
out_ids.append(doc_id)
out_docs.append(documents[idx] if documents is not None else prev_doc)
meta = dict(prev_meta or {})
if metadatas is not None:View on GitHub (pinned to 06cb6987f0)
Solutions
- Broadcast explicitly: metadatas = [meta] * len(ids) if you meant one value for all rows
- Rebuild arrays with zip(ids, ...) so they cannot drift from ids
- Add a pre-call assertion: assert all(v is None or len(v) == len(ids) for v in (documents, metadatas, embeddings))
- The error message names the offending label — check that array's construction logic first
Example fix
# before
collection.update(ids=ids, metadatas=[{"seen": True}]) # 1 != len(ids)
// after
collection.update(ids=ids, metadatas=[{"seen": True}] * len(ids)) Defensive patterns
Strategy: validation
Validate before calling
assert all(v is None or len(v) == len(ids) for v in (documents, metadatas, embeddings))
Prevention
- Build parallel arrays with zip(ids, ...) so they cannot drift
- Broadcast single values explicitly: metadatas=[m] * len(ids)
When it happens
Trigger: Calling update(ids=['a','b','c'], metadatas=[m1]) or similar — e.g. passing a single metadata dict meant for all rows, or building arrays in a loop that appends conditionally so some rows are skipped.
Common situations: Caller passes one shared value instead of a per-id list (scalar/1-element broadcast mistake); array built with a filtered comprehension while ids weren't filtered; off-by-one in chunked update loops.
Related errors
- add ids must be unique
- update requires at least one of documents, metadatas, embedd
- 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/1e54296f53cdbc64.
Report an issue: GitHub.