{"record":{"id":"2aefe5671ca09b94","repo":"headroomlabs-ai/headroom","slug":"unknown-store-backend-config-store-backend","errorCode":null,"errorMessage":"Unknown store backend: {config.store_backend}","messagePattern":"Unknown store backend: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/memory/factory.py","lineNumber":141,"sourceCode":"        A MemoryStore implementation based on config.store_backend.\n\n    Raises:\n        ValueError: If the store backend is not supported.\n    \"\"\"\n    if config.store_backend == StoreBackend.SQLITE:\n        from headroom.memory.adapters.sqlite import SQLiteMemoryStore\n\n        return SQLiteMemoryStore(config.db_path)\n\n    if config.store_backend == StoreBackend.EXTERNAL:\n        return _load_external_backend(  # type: ignore[no-any-return]\n            _MEMORY_STORE_GROUP,\n            config.store_backend_name,\n            \"store_backend_name\",\n            config,\n        )\n\n    raise ValueError(f\"Unknown store backend: {config.store_backend}\")\n\n\ndef _create_embedder(config: MemoryConfig) -> Embedder:\n    \"\"\"Create or return a cached embedder backend.\n\n    The embedder is shared across every ``LocalBackend`` instance that\n    requests the same ``(embedder_backend, embedder_model)`` pair. This\n    matters for the per-project storage router, which can open many\n    backends in the same process and must not pay the\n    sentence-transformers / ONNX model-load cost more than once.\n\n    Args:\n        config: Memory system configuration.\n\n    Returns:\n        An Embedder implementation based on config.embedder_backend.\n\n    Raises:","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/memory/factory.py#L123-L159","documentation":"`_create_store` in the memory factory handled every known StoreBackend enum member (SQLITE, EXTERNAL, ...) and fell through to a defensive ValueError. With a complete enum this is only reachable when the enum value is not a real StoreBackend member — e.g. a monkeypatched, stale, or duck-typed value that compares unequal to all branches.","triggerScenarios":"Passing a string like \"sqlite\" where a StoreBackend enum is expected (string vs enum comparison fails); using a config object from an older headroom version whose enum lacks/misnames members; monkeypatching config.store_backend with an arbitrary object at test time.","commonSituations":"Version mismatch between headroom-ai packages where StoreBackend members were added/renamed; deserializing a config from YAML/JSON into a raw string instead of the enum; test doubles replacing the enum.","solutions":["Ensure store_backend is an actual StoreBackend enum member: config.store_backend = StoreBackend.SQLITE","Upgrade/downgrade all headroom-ai extras together so the enum matches the factory (pip install -U 'headroom-ai[proxy]')","If loading config from data, coerce explicitly: StoreBackend(raw_value) and catch ValueError at load time"],"exampleFix":"# before\nconfig = MemoryConfig(store_backend=\"sqlite\")  # raw string\n\n# after\nfrom headroom.memory.config import StoreBackend\nconfig = MemoryConfig(store_backend=StoreBackend.SQLITE)","handlingStrategy":"type-guard","validationCode":"from headroom.memory.config import StoreBackend\nassert isinstance(config.store_backend, StoreBackend), \\\n    f\"store_backend must be StoreBackend member, got {config.store_backend!r}\"","typeGuard":"def is_store_backend(v: object) -> bool:\n    return isinstance(v, StoreBackend)","tryCatchPattern":"try:\n    system = await create_memory_system(config)\nexcept ValueError as e:\n    if \"Unknown store backend\" in str(e):\n        raise ConfigError(\"store_backend is not a valid StoreBackend member\") from e\n    raise","preventionTips":["Always construct enums via StoreBackend(...) instead of passing raw strings","Validate deserialized configs with a from_dict that coerces enums and raises on unknown values","Keep headroom-ai extras version-locked to avoid enum/factory skew"],"tags":["memory","configuration","enums","version-drift"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}