{"record":{"id":"73e446f979e9e36d","repo":"Graphify-Labs/graphify","slug":"unknown-backend-backend-r-available-sorted-ba","errorCode":null,"errorMessage":"Unknown backend {backend!r}. Available: {sorted(BACKENDS)}","messagePattern":"Unknown backend (.+?)\\. Available: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"graphify/llm.py","lineNumber":1768,"sourceCode":"\n    Accepts ``str`` paths as well as ``Path``; string entries are coerced up\n    front so downstream helpers (``_partition_semantic_files``, ``_read_files``,\n    ``_build_image_refs``) can rely on ``Path`` semantics (#1386). FileSlice units\n    (from extract_corpus_parallel's oversized-doc slicing, #1369) pass through\n    untouched — Path(FileSlice) would raise (#1397/#1399).\n    \"\"\"\n    files = [f if isinstance(f, (Path, FileSlice)) else Path(f) for f in files]\n    if backend is None:\n        backend = detect_backend()\n        if backend is None:\n            raise ValueError(\n                \"No LLM backend configured. Set one of: GEMINI_API_KEY, ANTHROPIC_API_KEY, \"\n                \"OPENAI_API_KEY, DEEPSEEK_API_KEY, MOONSHOT_API_KEY, \"\n                \"AZURE_OPENAI_API_KEY+AZURE_OPENAI_ENDPOINT, OLLAMA_BASE_URL, \"\n                \"or AWS credentials. Pass backend= explicitly to select a provider.\"\n            )\n    if backend not in BACKENDS:\n        raise ValueError(f\"Unknown backend {backend!r}. Available: {sorted(BACKENDS)}\")\n\n    cfg = BACKENDS[backend]\n    key = api_key or _get_backend_api_key(backend)\n    if not key and backend == \"ollama\":\n        # Ollama ignores auth but the OpenAI client library requires a non-empty\n        # string. Use a placeholder and surface a visible warning so this never\n        # silently routes traffic without the user realising — see F-029.\n        ollama_url = _resolve_ollama_base_url(cfg.get(\"base_url\", \"\"))\n        _validate_ollama_base_url(ollama_url)\n        print(\n            \"[graphify] WARNING: ollama backend selected with no OLLAMA_API_KEY set; \"\n            f\"sending corpus to {ollama_url}. Set OLLAMA_API_KEY (any non-empty value) \"\n            \"to suppress this warning.\",\n            file=sys.stderr,\n        )\n        key = \"ollama\"\n    if not key and backend not in (\"bedrock\", \"claude-cli\"):\n        raise ValueError(","sourceCodeStart":1750,"sourceCodeEnd":1786,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/llm.py#L1750-L1786","documentation":"Raised by `extract_files_direct` when the supplied `backend` string is not a key in the `BACKENDS` registry. The message lists all valid names (`sorted(BACKENDS)`), e.g. gemini, claude, claude-cli, openai, kimi, deepseek, moonshot, azure, bedrock, ollama. It guards the dispatch chain (if backend == \"claude\" elif ...) from falling through silently.","triggerScenarios":"Passing a misspelled or unsupported backend: `backend=\"gpt4\"`, `backend=\"Claude\"` (case-sensitive), `backend=\"openai-compatible\"`, or a provider added in a newer graphify version used against an older install.","commonSituations":"Typos and casing mistakes; assuming an arbitrary provider name works because the API is 'OpenAI-compatible' (must use a registered backend name); version skew between docs and installed package.","solutions":["Use one of the names printed in the message's `Available: [...]` list, exactly and lowercase.","For custom OpenAI-compatible endpoints, check whether the installed version supports an override (e.g. base_url configuration under a registered backend name) rather than inventing a backend string.","Upgrade graphify if the docs mention a backend your install doesn't list."],"exampleFix":"# before\nextract_files_direct(files, root, backend=\"GPT4\")\n\n# after\nextract_files_direct(files, root, backend=\"openai\")","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"from graphify.llm import BACKENDS\n\ndef is_known_backend(name: str) -> bool:\n    \"\"\"True when name is a registered graphify backend (case-sensitive).\"\"\"\n    return isinstance(name, str) and name in BACKENDS\n\nassert is_known_backend(user_backend), f\"pick from {sorted(BACKENDS)}\"","tryCatchPattern":null,"preventionTips":["Validate any config-supplied backend string against `BACKENDS` before calling extraction.","Backend names are lowercase and exact — normalize user input with `.strip().lower()` and re-check membership."],"tags":["configuration","validation","backend"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}