{"record":{"id":"0d0b846eb4be2b1f","repo":"MemPalace/mempalace","slug":"metadatas-length-len-metadatas-does-not-match-i-0d0b84","errorCode":null,"errorMessage":"metadatas length {len(metadatas)} does not match ids length {n}","messagePattern":"metadatas length (.+?) does not match ids length (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/sqlite_exact.py","lineNumber":246,"sourceCode":"            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\nclass _SQLiteExactHandle:\n    def __init__(\n        self,\n        conn: sqlite3.Connection,\n        lock: threading.RLock,\n        palace_path: str,\n        *,\n        read_only: bool = False,\n        immutable: bool = False,\n    ):\n        self.conn = conn\n        self.lock = lock\n        self.palace_path = palace_path\n        self.read_only = read_only","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/sqlite_exact.py#L228-L264","documentation":"Raised by sqlite_exact's `_validate_write_batch`: the optional `metadatas` list was supplied but its length differs from `len(ids)`. Metadatas is optional (None is fine), but once present it must pair 1:1 with ids so each stored row gets the right metadata dict.","triggerScenarios":"Calling upsert/add with `metadatas=[...]` shorter or longer than `ids` — commonly one shared metadata dict passed bare instead of repeated per row, or a comprehension that drops entries where metadata is missing.","commonSituations":"Passing a single metadata dict when the API expects a list (e.g. `metadatas={\"wing\": \"x\"}`); building metadatas with `filter(None, ...)` while ids keep all items; merging metadata from a dict keyed by id where some ids have no entry.","solutions":["If all rows share metadata, repeat it: `metadatas=[meta] * len(ids)`.","Fill missing per-id metadata with `{}` instead of dropping entries: `metadatas = [per_id.get(i, {}) for i in ids]`.","Add a pre-call assert `len(metadatas) == len(ids)` in dev builds and tests."],"exampleFix":"# before\ncol.upsert(ids=ids, documents=docs, metadatas=[{\"wing\": \"alice\"}])  # 1 != N\n\n# after\ncol.upsert(ids=ids, documents=docs, metadatas=[{\"wing\": \"alice\"}] * len(ids))","handlingStrategy":"validation","validationCode":"def align_metadatas(ids, metadatas):\n    if metadatas is None:\n        return None\n    if len(metadatas) != len(ids):\n        raise ValueError(f\"metadatas {len(metadatas)} != ids {len(ids)}\")\n    return metadatas","typeGuard":null,"tryCatchPattern":"try:\n    col.upsert(ids=ids, documents=docs, metadatas=metas)\nexcept ValueError as e:\n    if \"metadatas length\" in str(e):\n        metas = metas * len(ids) if len(metas) == 1 else [{} for _ in ids]\n        col.upsert(ids=ids, documents=docs, metadatas=metas)","preventionTips":["Remember the API takes a LIST of dicts, one per row — never a bare dict.","Use `[meta] * len(ids)` for shared metadata.","Default missing per-id metadata to {} instead of dropping entries."],"tags":["sqlite-exact","batch-write","metadata","validation"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}