headroomlabs-ai/headroom · error · ValueError

{field_name} is required when backend is EXTERNAL; set it to

Error message

{field_name} is required when backend is EXTERNAL; set it to the entry-point name registered under '{group}'.

What it means

When a MemoryConfig sets a backend to the EXTERNAL mode, the factory resolves the implementation via setuptools entry points, which requires a name to look up. `_load_external_backend` raises ValueError when the corresponding *_backend_name field is empty/None, because there is no way to guess which registered plugin to load.

Source

Thrown at headroom/memory/factory.py:53

# BackendRouter. Without this cache, opening N project DBs would load
# the sentence-transformers / ONNX model N times.
_EMBEDDER_CACHE: dict[tuple[str, str, str], Embedder] = {}
_EMBEDDER_CACHE_LOCK = threading.Lock()


def _load_external_backend(
    group: str,
    name: str | None,
    field_name: str,
    config: MemoryConfig,
) -> Any:
    """Load a memory backend registered via setuptools entry points.

    Mirrors the pattern used by
    `headroom.cache.compression_store._create_default_ccr_backend`.
    """
    if not name:
        raise ValueError(
            f"{field_name} is required when backend is EXTERNAL; "
            f"set it to the entry-point name registered under '{group}'."
        )
    ep = next((e for e in entry_points(group=group) if e.name == name), None)
    if ep is None:
        raise ValueError(
            f"No entry point registered under '{group}' with name '{name}'. "
            f"Install the package that provides it."
        )
    return ep.load()(config)


async def create_memory_system(
    config: MemoryConfig | None = None,
) -> tuple[MemoryStore, VectorIndex, TextIndex, Embedder, MemoryCache | None]:
    """Create a complete memory system from configuration.

    This factory function creates and initializes all memory system components

View on GitHub (pinned to 322425c43b)

Solutions

  1. Set store_backend_name (or text_backend_name) to the exact entry-point name the plugin package registers, e.g. config.store_backend_name = "my-org-memory-store"
  2. Find registered names with `importlib.metadata.entry_points(group='headroom.memory.store')` (the group string shown in the message) and pick one
  3. If you actually wanted a built-in backend, switch store_backend back to SQLITE/enum default instead of EXTERNAL

Example fix

# before
config = MemoryConfig(store_backend=StoreBackend.EXTERNAL)
system = await create_memory_system(config)  # ValueError

# after
config = MemoryConfig(
    store_backend=StoreBackend.EXTERNAL,
    store_backend_name="acme-memory-store",
)
system = await create_memory_system(config)
Defensive patterns

Strategy: validation

Validate before calling

if config.store_backend == StoreBackend.EXTERNAL and not config.store_backend_name:
    raise ValueError("store_backend_name required for EXTERNAL store backend")
# same check for text_backend/text_backend_name

Type guard

def external_backend_ready(cfg: MemoryConfig) -> bool:
    if cfg.store_backend == StoreBackend.EXTERNAL and not cfg.store_backend_name:
        return False
    if cfg.text_backend == TextBackend.EXTERNAL and not cfg.text_backend_name:
        return False
    return True

Try / catch

try:
    system = await create_memory_system(config)
except ValueError as e:
    if "is required when backend is EXTERNAL" in str(e):
        # config error: fix and restart, do not retry
        raise ConfigError(str(e)) from e
    raise

Prevention

When it happens

Trigger: Setting config.store_backend = StoreBackend.EXTERNAL without config.store_backend_name, or config.text_backend = TextBackend.EXTERNAL without config.text_backend_name, then calling create_memory_system(config).

Common situations: Copy-pasting a config template that sets the backend enum but not the name; migrating from a built-in backend to a plugin and forgetting the name field; the plugin package defines the entry point under a different name than assumed.

Related errors


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