srbhr/Resume-Matcher · error · HTTPException
Failed to generate cover letter. Please try again.
Error message
Failed to generate cover letter. Please try again.
What it means
This 500 error is raised by the generate_cover_letter_endpoint when the call to generate_cover_letter() (an AI/LLM-backed helper) throws any exception. The endpoint wraps the generation call in a broad try/except, logs the underlying cause, and returns a generic retry-able message so internal AI errors are not leaked to the client.
Source
Thrown at apps/backend/app/routers/resumes.py:1827
# Get resume data
resume_data = resume.get("processed_data")
if not resume_data:
raise HTTPException(
status_code=400,
detail="Resume has no processed data. Please re-upload the resume.",
)
# Get language setting
language = get_content_language()
# Generate cover letter
try:
cover_letter_content = await generate_cover_letter(
resume_data, job["content"], language
)
except Exception as e:
logger.error(f"Cover letter generation failed: {e}")
raise HTTPException(
status_code=500,
detail="Failed to generate cover letter. Please try again.",
)
# Save to resume record
await db.update_resume(resume_id, {"cover_letter": cover_letter_content})
return GenerateContentResponse(
content=cover_letter_content,
message="Cover letter generated successfully",
)
@router.post("/{resume_id}/generate-outreach", response_model=GenerateContentResponse)
async def generate_outreach_endpoint(resume_id: str) -> GenerateContentResponse:
"""Generate an outreach message on-demand for an existing tailored resume.
This endpoint allows users to generate a cold outreach message after a resumeView on GitHub (pinned to 116f9cc3b0)
Solutions
- Check backend logs for 'Cover letter generation failed: <e>' to see the real cause
- Verify the LLM provider API key and quota in the backend environment
- Retry the request — transient provider timeouts/rate limits usually resolve
- Reduce resume/job description size if the payload may exceed model limits
Example fix
// before
curl -X POST /api/resumes/{id}/cover-letter # 500 generic
// after
# inspect server logs first, e.g.
docker logs backend | grep 'Cover letter generation failed' Defensive patterns
Strategy: try-catch
Validate before calling
const resume = await getResume(resumeId);
const job = await getJob(jobId);
if (!resume?.processedData || !job?.content) throw new Error('Missing inputs for cover letter generation'); Try / catch
try {
await api.generateCoverLetter(resumeId);
} catch (e) {
if (e.response?.status === 500) {
// inspect server logs / retry after checking LLM provider health
await sleep(1000);
return retryOnce(() => api.generateCoverLetter(resumeId));
}
throw e;
} Prevention
- Monitor LLM provider status/quotas before batch generation
- Log the underlying exception server-side and alert on it
- Set explicit timeouts and retries around the AI helper call
- Validate resume_data and job content size before sending to the model
When it happens
Trigger: POSTing to the cover-letter generation route with valid resume_id/job context, but generate_cover_letter() fails — e.g. LLM API timeout, rate limit, invalid API key, malformed resume_data, or content that the model rejects.
Common situations: Expired or missing LLM API credentials in the environment, upstream provider outage or 429 rate limiting, oversized resume/job-description content exceeding the model context window, or network egress blocked from the backend.
Related errors
- Failed to generate outreach message. Please try again.
- Resume not found: {resume_id}
- 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
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/6289efe71276b846.
Report an issue: GitHub.