srbhr/Resume-Matcher · error · HTTPException
Failed to generate outreach message. Please try again.
Error message
Failed to generate outreach message. Please try again.
What it means
This 500 is raised by generate_outreach_endpoint when generate_outreach_message() throws any exception. The endpoint catches it, logs 'Outreach message generation failed', and returns a generic client-safe message while preserving the real cause in server logs.
Source
Thrown at apps/backend/app/routers/resumes.py:1898
# 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 outreach message
try:
outreach_content = await generate_outreach_message(
resume_data, job["content"], language
)
except Exception as e:
logger.error(f"Outreach message generation failed: {e}")
raise HTTPException(
status_code=500,
detail="Failed to generate outreach message. Please try again.",
)
# Save to resume record
await db.update_resume(resume_id, {"outreach_message": outreach_content})
return GenerateContentResponse(
content=outreach_content,
message="Outreach message generated successfully",
)
@router.post(
"/{resume_id}/generate-interview-prep",
response_model=GenerateInterviewPrepResponse,
)
async def generate_interview_prep_endpoint(View on GitHub (pinned to 116f9cc3b0)
Solutions
- Check backend logs for 'Outreach message generation failed: <e>' to find the root cause
- Validate the LLM API key and account quota in the backend environment
- Retry — transient provider errors often succeed on a second attempt
- Trim or truncate the resume/job description if the payload is too large
Example fix
// before
await generateOutreach(tailoredResume.id); // 500 generic
// after
try {
await generateOutreach(tailoredResume.id);
} catch (e) {
// check server logs for the underlying AI error, then retry
} Defensive patterns
Strategy: retry
Validate before calling
const resume = await getResume(resumeId);
const improvement = await getImprovementByTailoredResume(resumeId);
if (!resume?.processedData || !improvement?.jobId) throw new Error('Invalid inputs for outreach generation'); Try / catch
try {
await api.generateOutreach(resumeId);
} catch (e) {
if (e.response?.status === 500) {
// transient AI failure most likely: check server logs, then retry with backoff
await sleep(2000);
return api.generateOutreach(resumeId);
}
throw e;
} Prevention
- Alert on 'Outreach message generation failed' log lines
- Add retry-with-backoff around the LLM helper for 429/timeout errors
- Keep the LLM API key valid and monitor quota usage
- Cap combined resume+job prompt size to stay within model limits
When it happens
Trigger: POSTing to the outreach route with valid resume/job context, but the AI helper fails — LLM API timeout, rate limiting, invalid API key, or resume/job content the model cannot handle.
Common situations: Missing/expired LLM provider credentials, upstream provider outage or 429s, oversized combined resume+job-description payload, blocked network egress.
Related errors
- Failed to generate cover letter. 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/7eaec78b18b28817.
Report an issue: GitHub.