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
PgVectorCollection.update() validates that every provided parallel array (documents, metadatas, embeddings) has the same length as the ids list before touching the database. If any one of them differs, it raises this ValueError immediately, so no partial update can be written. This mirrors the batch-invariants enforced by the base backend interface and ChromaDB-style APIs.
Source
Thrown at mempalace/backends/pgvector.py:1005
"embedding": vector,
"updated_at": _utcnow(),
}
for doc_id, doc, meta, vector in zip(ids, documents, metadatas, vectors)
]
self._client.upsert_rows(self._table, rows)
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:
meta.update(metadatas[idx] or {})
out_metas.append(meta)
out_embeddings.append(embeddings[idx] if embeddings is not None else prev_embedding)View on GitHub (pinned to 06cb6987f0)
Solutions
- Make all arrays the same length before calling update(), e.g. assert len(ids) == len(documents or ids) == len(metadatas or ids).
- Build the batch as a single list of records ({id, document, metadata, embedding}) and derive the parallel arrays with zip(*(...)) so they cannot diverge.
- Pass None for arrays you are not updating instead of an empty or stale list.
Example fix
# before collection.update(ids=ids, documents=new_docs, metadatas=metas) # len mismatch # after assert len(ids) == len(new_docs) == len(metas) collection.update(ids=ids, documents=new_docs, metadatas=metas)
Defensive patterns
Strategy: validation
Validate before calling
def safe_update(col, ids, documents=None, metadatas=None, embeddings=None):
n = len(ids)
for name, arr in (("documents", documents), ("metadatas", metadatas), ("embeddings", embeddings)):
if arr is not None and len(arr) != n:
raise ValueError(f"{name} length {len(arr)} != ids length {n}")
return col.update(ids=ids, documents=documents, metadatas=metadatas, embeddings=embeddings) Type guard
def is_aligned_batch(ids, **arrays) -> bool:
return all(v is None or len(v) == len(ids) for v in arrays.values()) Try / catch
try:
col.update(ids=ids, documents=docs, metadatas=metas)
except ValueError as e:
if "does not match ids length" in str(e):
logger.error("batch misaligned", len_ids=len(ids))
raise Prevention
- Derive ids/documents/metadatas/embeddings from a single list of records so they cannot diverge.
- Add an assert of equal lengths at the top of every ingest function.
- Pass None instead of empty lists for arrays you are not updating.
When it happens
Trigger: Calling collection.update(ids=["a","b"], documents=["one doc"]) or update(ids=["a"], metadatas=[m1, m2], embeddings=[[...]]) — any call where len(documents), len(metadatas), or len(embeddings) differs from len(ids).
Common situations: Building the ids list and the metadata list in separate loops that append under different conditions; slicing one array but not another (docs[:-1] vs ids); reusing a batch-upsert helper that drops malformed entries from only one array before calling update().
Related errors
- query requires query_embeddings
- query input must be a non-empty list
- documents length {len(documents)} does not match ids length
- metadatas length {len(metadatas)} does not match ids length
- embeddings length {len(embeddings)} does not match ids lengt
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/e63bd3017b03df0f.
Report an issue: GitHub.