Graphify-Labs/graphify · error · ValueError

Unknown backend {backend!r}

Error message

Unknown backend {backend!r}

What it means

Raised by the lightweight `call_llm` helper (used e.g. by `graphify.dedup`'s LLM tiebreaker) when the given `backend` string is not in the `BACKENDS` registry. It mirrors `extract_files_direct`'s dispatch validation (error 54) but for callers that don't need the extraction prompt/JSON parsing. Unlike error 54 it doesn't list available names in the message.

Source

Thrown at graphify/llm.py:2573

) -> str:
    """Send a plain-text prompt to `backend` and return the model's text reply.

    When ``usage_out`` is provided it is accumulated in place with ``input`` and
    ``output`` token counts from the response, so callers (community labeling)
    can total the cost of otherwise-uninstrumented LLM calls (#1694). Existing
    callers that omit it are unaffected.

    Used by lightweight callers (e.g. `graphify.dedup` LLM tiebreaker) that
    don't need the full extraction prompt or JSON-shaped output. Mirrors the
    backend dispatch logic of `extract_files_direct` but skips the
    `_EXTRACTION_SYSTEM` prompt and JSON parsing.

    Previously `graphify.dedup` imported a `_call_llm` symbol that did not
    exist in this module, so the LLM tiebreaker silently no-op'd on
    `ImportError` (F-038). Adding the function here re-enables it.
    """
    if backend not in BACKENDS:
        raise ValueError(f"Unknown backend {backend!r}")
    cfg = BACKENDS[backend]
    key = _get_backend_api_key(backend)
    if not key and backend == "ollama":
        ollama_url = _resolve_ollama_base_url(cfg.get("base_url", ""))
        _validate_ollama_base_url(ollama_url)
        key = "ollama"
    if not key and backend not in ("bedrock", "claude-cli"):
        raise ValueError(
            f"No API key for backend '{backend}'. Set {_format_backend_env_keys(backend)}."
        )
    mdl = model or _default_model_for_backend(backend)

    def _rec(inp, out) -> None:
        if usage_out is not None:
            usage_out["input"] = usage_out.get("input", 0) + int(inp or 0)
            usage_out["output"] = usage_out.get("output", 0) + int(out or 0)

    if backend == "claude":

View on GitHub (pinned to 7fe58b0b0f)

Solutions

  1. Use a registered backend key — check `from graphify.llm import BACKENDS; sorted(BACKENDS)` for the exact names.
  2. Validate config-supplied backend strings against BACKENDS before calling call_llm.
  3. Upgrade graphify if the backend you want exists only in newer versions.

Example fix

# before
from graphify.llm import call_llm
call_llm("...", backend="OpenAI")

# after
from graphify.llm import call_llm, BACKENDS
backend = "openai" if "openai" in BACKENDS else "gemini"
call_llm("...", backend=backend)
Defensive patterns

Strategy: type-guard

Type guard

from graphify.llm import BACKENDS

def is_known_backend(name: str) -> bool:
    return isinstance(name, str) and name in BACKENDS

if not is_known_backend(cfg["llm_backend"]):
    raise ValueError(f"{cfg['llm_backend']!r} not in {sorted(BACKENDS)}")

Prevention

When it happens

Trigger: Calling `call_llm(prompt, backend="gpt")`, `call_llm(..., backend="Azure")`, or any unregistered/case-mismatched name; passing a provider label read from user config without validating it against BACKENDS.

Common situations: Free-text backend fields in user configs; typos; assuming a provider alias works; code written against a newer graphify that added backends, run on an older install lacking them.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/ef026d5a825b6c7d. Report an issue: GitHub.