headroomlabs-ai/headroom · error · FileNotFoundError
HNSW index not found: {hnsw_path}
Error message
HNSW index not found: {hnsw_path} What it means
Raised by HNSWVectorIndex.load_index when the expected .hnsw graph file does not exist at the derived path (path.with_suffix('.hnsw')). The loader treats a missing index file as a hard error rather than silently starting empty, so callers must handle first-run scenarios explicitly.
Source
Thrown at headroom/memory/adapters/hnsw.py:852
def load_index(self, path: str | Path) -> None:
"""Load the index from disk.
Loads both the HNSW index and all metadata/mappings.
Args:
path: Base path for the saved files.
Raises:
FileNotFoundError: If the index files don't exist.
ValueError: If the saved dimension doesn't match.
"""
path = Path(path)
hnsw_path = path.with_suffix(".hnsw")
meta_path = path.with_suffix(".meta")
if not hnsw_path.exists():
raise FileNotFoundError(f"HNSW index not found: {hnsw_path}")
if not meta_path.exists():
raise FileNotFoundError(f"Metadata file not found: {meta_path}")
# Load metadata first to get parameters
with open(meta_path) as f:
meta_data = json.load(f)
# Verify dimension matches
saved_dimension = meta_data["dimension"]
if saved_dimension != self._dimension:
raise ValueError(
f"Saved index dimension {saved_dimension} does not match "
f"current dimension {self._dimension}"
)
with self._lock:
# Update parameters
self._max_elements = meta_data["max_elements"]View on GitHub (pinned to 322425c43b)
Solutions
- Guard with Path.exists(): if the .hnsw file is absent, build a fresh index (and optionally save it) instead of loading.
- Verify the exact derived path — load_index appends '.hnsw' via with_suffix, so 'myindex' loads 'my.hnsw' if the stem looks like a suffix; prefer a path without dots.
- If the file was deleted unintentionally, restore it or re-index from the source of truth.
Example fix
// before
await index.load_index(path) # crashes on first run
// after
if path.with_suffix('.hnsw').exists():
await index.load_index(path)
else:
for m in memories:
await index.add_memory(m)
index.save_index(path) Defensive patterns
Strategy: type-guard
Validate before calling
if not path.with_suffix('.hnsw').exists():
# first run: build fresh
index = HNSWVectorIndex(dimension=embedder.dimension)
else:
await index.load_index(path) Type guard
from pathlib import Path
def index_files_exist(base: Path) -> bool:
return base.with_suffix('.hnsw').exists() and base.with_suffix('.meta').exists() Try / catch
try:
await index.load_index(path)
except FileNotFoundError:
for m in memories:
await index.add_memory(m)
index.save_index(path) Prevention
- Remember load_index derives filenames via with_suffix('.hnsw') — avoid dots in the base path.
- Treat a missing index as a normal first-run case, not an exception path.
When it happens
Trigger: Calling load_index on a fresh install where nothing was saved yet; passing a base path whose suffix substitution points elsewhere (e.g. 'index.v1' becomes 'index.hnsw'); deleted or moved index files.
Common situations: First run of an app before any save_index; typos in the path; with_suffix('.hnsw') surprising developers who expected the literal filename to be used; clearing caches/data directories.
Related errors
- Metadata file not found: {meta_path}
- Saved index dimension {saved_dimension} does not match curre
- deployment profile '{profile}' is corrupt ({path}): {e}
- hnswlib is required for HNSWVectorIndex. Install with: pip i
- save_path must be provided when auto_save is True
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/871d6b9e5db6662d.
Report an issue: GitHub.