{"record":{"id":"55132b35e7a26f50","repo":"headroomlabs-ai/headroom","slug":"saved-index-dimension-saved-dimension-does-not-m","errorCode":null,"errorMessage":"Saved index dimension {saved_dimension} does not match current dimension {self._dimension}","messagePattern":"Saved index dimension (.+?) does not match current dimension (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/memory/adapters/hnsw.py","lineNumber":863,"sourceCode":"            ValueError: If the saved dimension doesn't match.\n        \"\"\"\n        path = Path(path)\n        hnsw_path = path.with_suffix(\".hnsw\")\n        meta_path = path.with_suffix(\".meta\")\n\n        if not hnsw_path.exists():\n            raise FileNotFoundError(f\"HNSW index not found: {hnsw_path}\")\n        if not meta_path.exists():\n            raise FileNotFoundError(f\"Metadata file not found: {meta_path}\")\n\n        # Load metadata first to get parameters\n        with open(meta_path) as f:\n            meta_data = json.load(f)\n\n        # Verify dimension matches\n        saved_dimension = meta_data[\"dimension\"]\n        if saved_dimension != self._dimension:\n            raise ValueError(\n                f\"Saved index dimension {saved_dimension} does not match \"\n                f\"current dimension {self._dimension}\"\n            )\n\n        with self._lock:\n            # Update parameters\n            self._max_elements = meta_data[\"max_elements\"]\n            self._ef_construction = meta_data[\"ef_construction\"]\n            self._m = meta_data[\"m\"]\n            self._ef_search = meta_data[\"ef_search\"]\n\n            # Restore bounding parameters (with defaults for backward compatibility)\n            self._max_entries = meta_data.get(\"max_entries\")\n            self._eviction_batch_size = meta_data.get(\"eviction_batch_size\", 100)\n            self._eviction_count = meta_data.get(\"eviction_count\", 0)\n\n            # Create new index and load from file\n            self._index = hnswlib.Index(space=\"cosine\", dim=self._dimension)  # type: ignore[union-attr]","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/memory/adapters/hnsw.py#L845-L881","documentation":"Raised by HNSWVectorIndex.load_index when the dimension recorded in the .meta file differs from the current index instance's dimension. A saved HNSW graph can only be loaded into an index configured for the same vector space, so this guard prevents mixing incompatible embeddings.","triggerScenarios":"Constructing HNSWVectorIndex(dimension=384) (or using a default) then loading a file saved with dimension=768; loading an index saved before switching embedding models.","commonSituations":"Embedding model upgrade without recreating the on-disk index; environment-specific defaults disagreeing; the constructor default silently used instead of the model's dimension.","solutions":["Construct the index with the dimension recorded in the .meta file (read meta_data['dimension'] first), or re-embed everything and save a new index.","After changing embedders, version your index paths (e.g. index-miniLM.hnsw vs index-llm.hnsw) so old files are never loaded with new dimensions.","Delete the stale files and rebuild from the memory store."],"exampleFix":"// before\nindex = HNSWVectorIndex(dimension=384)\nawait index.load_index(path)  # saved with 768\n\n// after\nmeta = json.loads(path.with_suffix('.meta').read_text())\nindex = HNSWVectorIndex(dimension=meta['dimension'])\nawait index.load_index(path)","handlingStrategy":"validation","validationCode":"meta = json.loads(path.with_suffix('.meta').read_text())\nindex = HNSWVectorIndex(dimension=meta['dimension'])\nawait index.load_index(path)","typeGuard":null,"tryCatchPattern":"try:\n    await index.load_index(path)\nexcept ValueError as e:\n    if \"dimension\" in str(e):\n        # stale index from another model: rebuild\n        await rebuild_index(index, memories)","preventionTips":["Version index filenames per embedding model.","Always construct the index with the dimension from the saved metadata when loading."],"tags":["hnsw","dimension-mismatch","persistence","load"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}