srbhr/Resume-Matcher · error · ValueError
LLM completion failed. Please check your API configuration a
Error message
LLM completion failed. Please check your API configuration and try again.
What it means
complete() in llm.py wraps every failure of the underlying LiteLLM completion call (network errors, auth errors, bad model names, empty/thinking-only responses) in a single generic ValueError. The real cause is logged server-side, but the client-facing message only tells you to check your API configuration.
Source
Thrown at apps/backend/app/llm.py:810
if config.reasoning_effort:
kwargs["reasoning_effort"] = config.reasoning_effort
response = await router.acompletion(**kwargs)
content = _extract_choice_text(response.choices[0])
if not content:
raise ValueError("Empty response from LLM")
# Strip thinking tags from reasoning models (deepseek-r1, qwq, etc.)
if "<think>" in content:
content = _strip_thinking_tags(content)
if not content:
raise ValueError("Response contained only thinking content, no output")
return content
except Exception as e:
# Log the actual error server-side for debugging
logging.error(f"LLM completion failed: {e}", extra={
"model": model_name})
raise ValueError(
"LLM completion failed. Please check your API configuration and try again."
) from e
def _supports_json_mode(model_name: str) -> bool:
"""Check if the model supports JSON mode via LiteLLM's model registry.
Queries LiteLLM's model info for every provider (including openai,
anthropic, etc.) so that capability is always determined from the
registry rather than a hardcoded provider list.
Ollama models support JSON mode natively (format="json") but are
often not in LiteLLM's registry (custom/local models), so we
always return True for ollama.
Args:
model_name: LiteLLM-formatted model name (from get_model_name).
"""View on GitHub (pinned to 116f9cc3b0)
Solutions
- Check the server logs for the 'LLM completion failed: ...' line — it contains the true underlying error
- Verify the provider API key env var (e.g. OPENAI_API_KEY/ANTHROPIC_API_KEY) is set and valid
- Confirm the configured model_name is correct and supported by your provider/LiteLLM registry
- Test connectivity to the LLM endpoint and retry in case of a transient provider outage
Example fix
// before
const text = await complete(prompt, config); // throws generic ValueError
// after
try {
const text = await complete(prompt, config);
} catch (e) {
showUser('AI generation failed — please retry');
logServer(e); // real cause is already logged by llm.py
} Defensive patterns
Strategy: try-catch
Validate before calling
import os
def llm_config_ready() -> bool:
key = os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")
return bool(key) and bool(os.getenv("LLM_MODEL")) Try / catch
try:
content = await complete(prompt, config=config)
except ValueError as e:
logger.error("LLM call failed; see llm.py server log for root cause")
return fallback_response("AI service temporarily unavailable, please retry") Prevention
- Check server logs for 'LLM completion failed: ...' — the real cause is logged there
- Validate API keys and model names at startup with a smoke-test call
- Set alerts on provider error rates/outages
- Prefer models whose names are verified against the LiteLLM registry
When it happens
Trigger: Any exception inside complete() — LLM provider HTTP error, invalid/missing API key, unsupported model_name, rate limit, timeout, or a response containing only <think> content with no output.
Common situations: Expired or absent provider API key env var; model name not registered with the provider; proxy/firewall blocking the endpoint; provider outage; reasoning model returning only thinking tags.
Related errors
- JSON extraction exceeded max recursion depth: {_depth}
- Content too large for JSON extraction: {len(content)} bytes
- No JSON found in response: {original[:200]}
- Empty response from LLM
- Failed to parse JSON after {retries + 1} attempts: {e}
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/68b1df052acbfb90.
Report an issue: GitHub.