headroomlabs-ai/headroom · error · ValueError
Unknown backend: {self._backend_type}
Error message
Unknown backend: {self._backend_type} What it means
The high-level Memory facade only recognizes two backend names: "local" and "qdrant-neo4j". Any other string passed as the `backend` argument reaches the final else branch in `_ensure_initialized` and raises ValueError. Initialization is lazy, so the error surfaces on the first save/search/delete/clear call, not at construction.
Source
Thrown at headroom/memory/easy.py:186
mem0_config = Mem0Config(
qdrant_url=self._qdrant_url,
qdrant_host=self._qdrant_host,
qdrant_port=self._qdrant_port,
qdrant_api_key=self._qdrant_api_key,
neo4j_uri=self._neo4j_uri,
neo4j_user=self._neo4j_user,
neo4j_password=self._neo4j_password,
enable_graph=True,
)
self._backend = DirectMem0Adapter(mem0_config)
except ImportError as e:
raise ImportError(
"qdrant-neo4j backend requires additional packages. "
"Install with: pip install 'headroom-ai[memory-stack]'\n"
"And start Docker services: docker compose up -d qdrant neo4j"
) from e
else:
raise ValueError(f"Unknown backend: {self._backend_type}")
self._initialized = True
async def save(
self,
content: str,
user_id: str,
importance: float = 0.5,
facts: list[str] | None = None,
entities: list[dict[str, str]] | None = None,
relationships: list[dict[str, str]] | None = None,
metadata: dict[str, Any] | None = None,
) -> str:
"""Save a memory.
Args:
content: The memory content to save.
user_id: User identifier for scoping memories.View on GitHub (pinned to 322425c43b)
Solutions
- Use backend="local" for the SQLite-backed local memory (default) or backend="qdrant-neo4j" for the mem0 Qdrant+Neo4j stack
- If you need a custom/external backend, use the lower-level factory (headroom.memory.factory.create_memory_system) with StoreBackend.EXTERNAL and an entry-point name instead of the Memory facade
- Check the installed version's Memory docstring (help(Memory)) to confirm supported backend literals
- Fail fast: call `await memory._ensure_initialized()` or a trivial operation right after construction to surface config errors at startup
Example fix
# before
memory = Memory(backend="mem0")
id = await memory.save("note", user_id="alice") # ValueError: Unknown backend: mem0
# after
memory = Memory(backend="qdrant-neo4j",
qdrant_url="https://xyz.cloud.qdrant.io:6333",
qdrant_api_key="...")
id = await memory.save("note", user_id="alice") Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {"local", "qdrant-neo4j"}
if memory_backend not in SUPPORTED:
raise ValueError(f"backend must be one of {sorted(SUPPORTED)}, got {memory_backend!r}")
memory = Memory(backend=memory_backend) Type guard
def is_memory_backend(v: str) -> bool:
return v in {"local", "qdrant-neo4j"} Try / catch
try:
await memory.save(content, user_id=uid)
except ValueError as e:
if "Unknown backend" in str(e):
raise ConfigError(f"fix Memory(backend=...): {e}") from e
raise Prevention
- Validate the backend string at config load, not at first memory operation
- Smoke-test Memory right after construction (e.g. await a cheap search) so backend errors fail at startup
- Keep backend names in one constant instead of scattering string literals
When it happens
Trigger: Calling `Memory(backend="sqlite")`, `Memory(backend="mem0")`, `Memory(backend="qdrant")`, or passing a typo'd/None-coerced string, then awaiting any method (e.g. `await memory.save(...)`). Constructor succeeds silently; the first backend operation raises.
Common situations: Developers guess backend names from the ecosystem (mem0, qdrant, neo4j, sqlite) instead of the two supported literals; passing a StoreBackend enum value meant for MemoryConfig into the easy facade; version drift after backend names were renamed in an upgrade.
Related errors
- bedrock_eventstream_parse_failed
- max_size must be at least 1, got {max_size}
- save_path must be provided when auto_save is True
- bedrock_eventstream_crc_mismatch
- Unknown provider: {self.llm_config.provider}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/bcb94d19804fe7c5.
Report an issue: GitHub.