{"record":{"id":"a9bfdb828e8b2a37","repo":"langchain-ai/langchain","slug":"length-of-keys-must-match-length-of-group-ids","errorCode":null,"errorMessage":"Length of keys must match length of group_ids","messagePattern":"Length of keys must match length of group_ids","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/indexing/base.py","lineNumber":298,"sourceCode":"            group_ids: A list of group IDs corresponding to the keys.\n\n            time_at_least: Optional timestamp. Implementation can use this\n                to optionally verify that the timestamp IS at least this time\n                in the system that stores.\n                E.g., use to validate that the time in the postgres database\n                is equal to or larger than the given timestamp, if not\n                raise an error.\n                This is meant to help prevent time-drift issues since\n                time may not be monotonically increasing!\n\n        Raises:\n            ValueError: If the length of keys doesn't match the length of group\n                ids.\n            ValueError: If time_at_least is in the future.\n        \"\"\"\n        if group_ids and len(keys) != len(group_ids):\n            msg = \"Length of keys must match length of group_ids\"\n            raise ValueError(msg)\n        for index, key in enumerate(keys):\n            group_id = group_ids[index] if group_ids else None\n            if time_at_least and time_at_least > self.get_time():\n                msg = \"time_at_least must be in the past\"\n                raise ValueError(msg)\n            self.records[key] = {\"group_id\": group_id, \"updated_at\": self.get_time()}\n\n    async def aupdate(\n        self,\n        keys: Sequence[str],\n        *,\n        group_ids: Sequence[str | None] | None = None,\n        time_at_least: float | None = None,\n    ) -> None:\n        \"\"\"Async upsert records into the database.\n\n        Args:\n            keys: A list of record keys to upsert.","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/indexing/base.py#L280-L316","documentation":"`ValueError` from `RecordManager.update` (and mirrored in `aupdate`): the `keys` sequence and the optional `group_ids` sequence have different lengths. Each key must be paired with exactly one group ID, so a mismatch means the caller's data is malformed and the upsert is rejected before any record is written.","triggerScenarios":"Calling `record_manager.update(keys, group_ids=group_ids)` where `len(keys) != len(group_ids)` — e.g. computing group IDs for a filtered subset of keys, or passing a single group ID string instead of a one-element list when updating one key.","commonSituations":"Custom RecordManager callers (the built-in indexer always passes matched lengths); passing `group_ids=[\"g\"]` with `keys=[\"a\",\"b\"]`; list comprehensions where the group-ids comprehension filters or drops entries.","solutions":["Make group IDs line up 1:1: `group_ids=[group_for(k) for k in keys]`.","For a shared group across all keys: `group_ids=[group] * len(keys)`.","Add a guard before the call: `if group_ids is not None: assert len(keys) == len(group_ids)`."],"exampleFix":"# before\nrecord_manager.update([\"k1\", \"k2\", \"k3\"], group_ids=[\"g1\", \"g2\"])\n\n# after\nrecord_manager.update([\"k1\", \"k2\", \"k3\"], group_ids=[\"g1\", \"g2\", \"g3\"])","handlingStrategy":"validation","validationCode":"if group_ids is not None:\n    assert len(keys) == len(group_ids), f\"{len(keys)} keys vs {len(group_ids)} group_ids\"","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Derive group_ids from keys with a comprehension so lengths match by construction","Use [group] * len(keys) for a shared group","Keep record-manager calls in one helper you can test"],"tags":["record-manager","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}