srbhr/Resume-Matcher · error · ValueError
Failed after {retries + 1} attempts
Error message
Failed after {retries + 1} attempts What it means
complete_json loops for up to retries + 1 attempts; if the loop exits without returning (all attempts consumed by content-quality failures that didn't raise), it raises this generic ValueError. Transport errors are re-raised as-is since the LiteLLM Router already retried with backoff.
Source
Thrown at apps/backend/app/llm.py:1360
):
json_mode_failed = True
logging.warning(
"Provider rejected response_format for %s; falling back to "
"prompt-only JSON mode (attempt %d)",
model_name,
attempt + 1,
)
if attempt < retries:
continue
raise
except Exception:
# Transport errors — Router already retried with backoff.
# Cooldowns are disabled (see _build_router); no additional
# retry is attempted here.
raise
raise ValueError(f"Failed after {retries + 1} attempts")
View on GitHub (pinned to 116f9cc3b0)
Solutions
- Increase retries in the complete_json call
- Check server logs for the per-attempt warnings ('Content extraction failed (attempt N)') to find the root cause
- Switch to a stronger model or enable JSON mode for the request
- Add a fallback UX (cached result or graceful degradation) in the calling feature (analyze_resume, generate_enhancements, etc.)
Defensive patterns
Strategy: try-catch
Validate before calling
async def llm_healthy() -> bool:
try:
await complete_json('Return {"ok": true}', retries=1)
return True
except ValueError:
return False Try / catch
try:
data = await complete_json(prompt)
except ValueError:
# includes 'Failed after N attempts'
return serve_cached_or_default_result()
except Exception:
# transport errors — Router already retried; surface as 503
raise ServiceUnavailable("LLM provider unreachable") Prevention
- Configure a sensible retries value for all complete_json calls
- Watch logs for repeated 'Content extraction failed' warnings — a sign of model/prompt mismatch
- Design caller features (analyze_resume, generate_enhancements) with fallbacks
- Health-check the LLM path at deploy time
When it happens
Trigger: Every attempt of complete_json fails with empty responses or extraction failures, the retry loop is exhausted, and the final raise at the end of the function is reached.
Common situations: Sustained provider degradation returning empty/bad content across all retries; retries configured to 0; model systematically unable to satisfy the prompt's JSON requirement.
Related errors
- Failed to parse JSON after {retries + 1} attempts: {e}
- LLM completion failed. Please check your API configuration a
- JSON extraction exceeded max recursion depth: {_depth}
- Content too large for JSON extraction: {len(content)} bytes
- No JSON found in response: {original[:200]}
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/1c31033541fd5efc.
Report an issue: GitHub.