headroomlabs-ai/headroom · error · ValueError

Unknown store backend: {config.store_backend}

Error message

Unknown store backend: {config.store_backend}

What it means

`_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.

Source

Thrown at headroom/memory/factory.py:141

        A MemoryStore implementation based on config.store_backend.

    Raises:
        ValueError: If the store backend is not supported.
    """
    if config.store_backend == StoreBackend.SQLITE:
        from headroom.memory.adapters.sqlite import SQLiteMemoryStore

        return SQLiteMemoryStore(config.db_path)

    if config.store_backend == StoreBackend.EXTERNAL:
        return _load_external_backend(  # type: ignore[no-any-return]
            _MEMORY_STORE_GROUP,
            config.store_backend_name,
            "store_backend_name",
            config,
        )

    raise ValueError(f"Unknown store backend: {config.store_backend}")


def _create_embedder(config: MemoryConfig) -> Embedder:
    """Create or return a cached embedder backend.

    The embedder is shared across every ``LocalBackend`` instance that
    requests the same ``(embedder_backend, embedder_model)`` pair. This
    matters for the per-project storage router, which can open many
    backends in the same process and must not pay the
    sentence-transformers / ONNX model-load cost more than once.

    Args:
        config: Memory system configuration.

    Returns:
        An Embedder implementation based on config.embedder_backend.

    Raises:

View on GitHub (pinned to 322425c43b)

Solutions

  1. Ensure store_backend is an actual StoreBackend enum member: config.store_backend = StoreBackend.SQLITE
  2. Upgrade/downgrade all headroom-ai extras together so the enum matches the factory (pip install -U 'headroom-ai[proxy]')
  3. If loading config from data, coerce explicitly: StoreBackend(raw_value) and catch ValueError at load time

Example fix

# before
config = MemoryConfig(store_backend="sqlite")  # raw string

# after
from headroom.memory.config import StoreBackend
config = MemoryConfig(store_backend=StoreBackend.SQLITE)
Defensive patterns

Strategy: type-guard

Validate before calling

from headroom.memory.config import StoreBackend
assert isinstance(config.store_backend, StoreBackend), \
    f"store_backend must be StoreBackend member, got {config.store_backend!r}"

Type guard

def is_store_backend(v: object) -> bool:
    return isinstance(v, StoreBackend)

Try / catch

try:
    system = await create_memory_system(config)
except ValueError as e:
    if "Unknown store backend" in str(e):
        raise ConfigError("store_backend is not a valid StoreBackend member") from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/2aefe5671ca09b94. Report an issue: GitHub.