{"record":{"id":"06898d45a5fa265c","repo":"headroomlabs-ai/headroom","slug":"hnsw-ef-construction-must-be-positive-got-self-h","errorCode":null,"errorMessage":"hnsw_ef_construction must be positive, got {self.hnsw_ef_construction}","messagePattern":"hnsw_ef_construction must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/memory/config.py","lineNumber":140,"sourceCode":"    embedder_model: str = field(default_factory=lambda: ML_MODEL_DEFAULTS.sentence_transformer)\n    openai_api_key: str | None = None\n    ollama_base_url: str = \"http://localhost:11434\"\n\n    # Cache\n    cache_enabled: bool = True\n    cache_max_size: int = 1000\n\n    # Bubbling defaults\n    auto_bubble: bool = True\n    bubble_threshold: float = 0.7  # Minimum importance for bubbling\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate configuration after initialization.\"\"\"\n        if self.vector_dimension < 1:\n            raise ValueError(f\"vector_dimension must be positive, got {self.vector_dimension}\")\n\n        if self.hnsw_ef_construction < 1:\n            raise ValueError(\n                f\"hnsw_ef_construction must be positive, got {self.hnsw_ef_construction}\"\n            )\n\n        if self.hnsw_m < 1:\n            raise ValueError(f\"hnsw_m must be positive, got {self.hnsw_m}\")\n\n        if self.hnsw_ef_search < 1:\n            raise ValueError(f\"hnsw_ef_search must be positive, got {self.hnsw_ef_search}\")\n\n        if self.cache_max_size < 1:\n            raise ValueError(f\"cache_max_size must be positive, got {self.cache_max_size}\")\n\n        if self.embedder_backend == EmbedderBackend.OPENAI and not self.openai_api_key:\n            raise ValueError(\"openai_api_key is required when using OpenAI embedder backend\")\n\n        # Ensure db_path is a Path object\n        if isinstance(self.db_path, str):\n            self.db_path = Path(self.db_path)","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/memory/config.py#L122-L158","documentation":"ValueError raised in MemoryConfig.__post_init__ when hnsw_ef_construction < 1. This parameter controls the HNSW index build quality (ef_construction); zero or negative values are invalid for the underlying ANN index and are rejected before any data is written.","triggerScenarios":"MemoryConfig(hnsw_ef_construction=0) or negative — usually a misread config where the operator meant to use the default and set 0, or a value loaded from an unset env var.","commonSituations":"'0 means default' conventions from other systems; tuning configs copied from docs with different parameter names; disabling-tuning attempts.","solutions":["Use a positive value; sane ranges are 100-500 (omit the field entirely to use the default)","Validate parsed numeric config before constructing MemoryConfig so 0/empty fails with context","Leave HNSW build params at defaults unless you have a measured reason to tune"],"exampleFix":"# before\ncfg = MemoryConfig(hnsw_ef_construction=0)  # ValueError\n\n# after\ncfg = MemoryConfig()  # defaults\ncfg = MemoryConfig(hnsw_ef_construction=200)  # or explicit positive tuning","handlingStrategy":"validation","validationCode":"def positive_int(name: str, v: int) -> int:\n    if v < 1:\n        raise ValueError(f'{name} must be >= 1, got {v}')\n    return v\n\ncfg = MemoryConfig(hnsw_ef_construction=positive_int('hnsw_ef_construction', raw_ef))","typeGuard":"def is_positive_int(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 1","tryCatchPattern":"try:\n    cfg = MemoryConfig(hnsw_ef_construction=raw_ef)\nexcept ValueError:\n    cfg = MemoryConfig()  # defaults","preventionTips":["Map '0'/'unset' in external config to omitting the field instead of passing 0","Keep HNSW build params at defaults unless benchmarked","Range-check generated configs in CI"],"tags":["python","config","validation","hnsw","vector-index","range-check"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}