{"record":{"id":"722b8829191d1b8c","repo":"MemPalace/mempalace","slug":"documents-length-len-documents-does-not-match-i-722b88","errorCode":null,"errorMessage":"documents length {len(documents)} does not match ids length {n}","messagePattern":"documents length (.+?) does not match ids length (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/qdrant.py","lineNumber":229,"sourceCode":"            continue\n        if key == \"$or\":\n            if not any(_matches_where_document(document, clause) for clause in value or []):\n                return False\n            continue\n        raise UnsupportedFilterError(f\"where_document operator {key!r} not supported\")\n    return True\n\n\ndef _validate_write_batch(\n    *,\n    documents: list[str],\n    ids: list[str],\n    metadatas: Optional[list[dict]],\n    embeddings: Optional[list[list[float]]],\n) -> None:\n    n = len(ids)\n    if len(documents) != n:\n        raise ValueError(f\"documents length {len(documents)} does not match ids length {n}\")\n    if metadatas is not None and len(metadatas) != n:\n        raise ValueError(f\"metadatas length {len(metadatas)} does not match ids length {n}\")\n    if embeddings is not None and len(embeddings) != n:\n        raise ValueError(f\"embeddings length {len(embeddings)} does not match ids length {n}\")\n\n\ndef _as_vector_array(vector: list[float]) -> np.ndarray:\n    arr = np.asarray(vector, dtype=np.float32)\n    if arr.ndim != 1 or arr.size == 0:\n        raise ValueError(\"embedding must be a non-empty 1D vector\")\n    return arr\n\n\ndef _normalize_vectors(embeddings: list[list[float]]) -> tuple[list[list[float]], int]:\n    vectors = []\n    dims = set()\n    for embedding in embeddings:\n        arr = _as_vector_array(embedding)","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/qdrant.py#L211-L247","documentation":"Before any upsert/add into the qdrant backend, _validate_write_batch checks that len(documents) equals len(ids). A mismatch raises ValueError immediately, so a malformed batch can never produce half-written points.","triggerScenarios":"collection.add(documents=[\"a\"], ids=[\"1\",\"2\"]) or upsert where the documents list was built from a different source than the ids list.","commonSituations":"Zipping/unzipping mismatches; filtering invalid rows out of documents but not ids; off-by-one slices on one array.","solutions":["Assert len(documents) == len(ids) before the call.","Derive documents, ids, metadatas, embeddings from one list of records via zip(*...).","Add a unit test over your batch builder that asserts equal lengths."],"exampleFix":"# before\ncol.add(ids=ids, documents=[d for d in docs if d])\n\n# after\nrecords = [(i, d) for i, d in zip(ids, docs) if d]\ncol.add(ids=[r[0] for r in records], documents=[r[1] for r in records])","handlingStrategy":"validation","validationCode":"assert len(documents) == len(ids), f\"documents {len(documents)} != ids {len(ids)}\"\ncol.add(ids=ids, documents=documents)","typeGuard":"def is_valid_write_batch(ids, documents) -> bool:\n    return len(documents) == len(ids)","tryCatchPattern":"try:\n    col.add(ids=ids, documents=documents)\nexcept ValueError as e:\n    if \"does not match ids length\" in str(e):\n        logger.error(\"ingest batch misaligned: %d ids vs %d docs\", len(ids), len(documents))\n        raise","preventionTips":["Build batches as a single list of records; derive parallel arrays with zip(*...).","Add a length assert in every ingest helper before calling add/upsert."],"tags":["qdrant","validation","batch-mismatch"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}