MemPalace/mempalace · error · KeyError

unknown backend {name!r}; available: {sorted(_registry.keys(

Error message

unknown backend {name!r}; available: {sorted(_registry.keys())}

What it means

Raised by get_backend() when the named backend class is not registered — the instance-caching variant of the same lookup failure as get_backend_class. The message enumerates currently registered backend names (sorted registry keys).

Source

Thrown at mempalace/backends/registry.py:122

        return _registry[name]
    except KeyError as e:
        raise KeyError(f"unknown backend {name!r}; available: {available_backends()}") from e


def get_backend(name: str) -> BaseBackend:
    """Return a long-lived instance of the named backend.

    Instances are cached per-name; repeated calls return the same object.
    Call :func:`reset_backends` in tests that need isolation.
    """
    _discover_entry_points()
    with _lock:
        inst = _instances.get(name)
        if inst is not None:
            return inst
        cls = _registry.get(name)
        if cls is None:
            raise KeyError(f"unknown backend {name!r}; available: {sorted(_registry.keys())}")
        inst = cls()
        _instances[name] = inst
        return inst


def detect_backends_for_path(path: str) -> list[str]:
    """Return all registered backend names whose artifacts are present at ``path``.

    Detection is a migration/protection aid for local palaces. Backends are
    checked in registry-name order so callers get deterministic diagnostics if
    a broken directory contains artifacts from more than one backend.
    """
    _discover_entry_points()
    detected = []
    for name in sorted(_registry):
        cls = _registry[name]
        try:
            if cls.detect(path):

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Use a name from the message's available list (verify with available_backends())
  2. Install the matching optional extra / plugin package
  3. Validate backend names against available_backends() at config load time, not at first use

Example fix

# before
backend = get_backend("sqlite")  # not registered
# after
from mempalace.backends.registry import available_backends
assert "sqlite_exact" in available_backends()
backend = get_backend("sqlite_exact")
Defensive patterns

Strategy: validation

Validate before calling

from mempalace.backends.registry import available_backends
AVAILABLE = set(available_backends())
if config.backend not in AVAILABLE:
    raise ConfigError(f"backend {config.backend!r} not in {sorted(AVAILABLE)}")
backend = get_backend(config.backend)

Type guard

def is_registered_backend(name: str) -> bool:
    return isinstance(name, str) and name in available_backends()

Try / catch

try:
    backend = get_backend(name)
except KeyError:
    name = pick_from(available_backends())  # prompt user or fail with clear message
    backend = get_backend(name)

Prevention

When it happens

Trigger: get_backend(name) with a typo'd/unregistered name, an optional backend whose dependency is not installed, or a plugin whose entry point did not load.

Common situations: Config-driven backend selection (env var / settings file) with a stale or misspelled value; deploying without the optional dependency for the configured backend; test code requesting a backend only registered under an extra.

Related errors


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/7572b341e274ed02. Report an issue: GitHub.