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
- Use a registered backend key — check `from graphify.llm import BACKENDS; sorted(BACKENDS)` for the exact names.
- Validate config-supplied backend strings against BACKENDS before calling call_llm.
- 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
- Validate user/config backend strings against BACKENDS before calling call_llm (used by graphify.dedup's tiebreaker).
- Expose the sorted BACKENDS list in your tool's validation error so users self-correct.
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
- Unknown backend {backend!r}. Available: {sorted(BACKENDS)}
- No LLM backend configured. Set one of: GEMINI_API_KEY, ANTHR
- No API key for backend '{backend}'. Set {_format_backend_env
- token_budget must be positive, got {token_budget}
- No API key for backend '{backend}'. Set {_format_backend_env
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/ef026d5a825b6c7d.
Report an issue: GitHub.