srbhr/Resume-Matcher · error · HTTPException

Resume not found

Error message

Resume not found

What it means

get_resume raises HTTP 404 when db.get_resume(resume_id) returns no document. This is the shared internal loader reused by get_application_detail, analyze_resume, generate_enhancements, apply_enhancements, regenerate_items and apply_regenerated_items, so a stale ID fails on every dependent endpoint.

Source

Thrown at apps/backend/app/routers/resumes.py:731

        request_id=str(uuid4()),
        resume_id=resume["resume_id"],
        processing_status=resume["processing_status"],
        is_master=resume.get("is_master", False),
    )


@router.get("", response_model=ResumeFetchResponse)
async def get_resume(resume_id: str = Query(...)) -> ResumeFetchResponse:
    """Fetch resume details by ID.

    Returns both raw markdown and structured data (if available),
    plus cover letter and outreach message if they exist.
    Applies lazy migration for section metadata if needed.
    """
    resume = await db.get_resume(resume_id)

    if not resume:
        raise HTTPException(status_code=404, detail="Resume not found")

    # Get processing status (default to "pending" for old records)
    processing_status = resume.get("processing_status", "pending")

    # Build response
    raw_resume = RawResume(
        id=None,  # TinyDB doesn't have numeric IDs like SQL
        content=resume["content"],
        content_type=resume["content_type"],
        created_at=resume["created_at"],
        processing_status=processing_status,
    )

    # Get processed data if available (no more on-demand parsing)
    processed_data = resume.get("processed_data")

    # Apply lazy migration - add section metadata to old resumes
    if processed_data:

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Confirm the resume_id in the request matches an existing record (list resumes via GET /resumes and compare)
  2. Re-create the resume if the database was reset, and refresh the client's stored ID
  3. Check that the frontend route parameter (e.g. useParams().id) is actually the resume ID, not an application or job ID
  4. Verify the backend is pointed at the intended database (MONGODB_URI / env selection)

Example fix

// before
fetch(`/api/resumes/${localStorage.id}`) // stale id from previous DB
// after: fetch fresh list first and use a valid id
const list = await fetch('/api/resumes').then(r => r.json());
fetch(`/api/resumes/${list.resumes[0].id}`)
Defensive patterns

Strategy: try-catch

Validate before calling

async function resumeExists(id: string): Promise<boolean> {
  const res = await fetch(`/api/resumes/${id}`);
  return res.ok;
}
if (!(await resumeExists(resumeId))) await refreshResumeList();

Type guard

function isResumeRef(r: unknown): r is {resume_id: string} & Record<string, unknown> {
  return typeof r === 'object' && r !== null &&
    typeof (r as any).resume_id === 'string' && (r as any).resume_id.length > 0;
}

Try / catch

try {
  const resume = await api.getResume(id);
} catch (e) {
  if (e.response?.status === 404) {
    invalidate(id); // drop stale ID, redirect to resume list / re-upload
  } else throw e;
}

Prevention

When it happens

Trigger: GET /resumes/{id} (or any caller passing a resume_id) where the ID does not exist in the database, was deleted, or the caller passes a truncated/mistyped ID (e.g. React Router param misconfiguration).

Common situations: Frontend uses a locally-generated UUID instead of the server-assigned ID; resume deleted in another tab; database was reset/reseeded while the client kept old IDs; wrong DB (dev vs prod) backing the backend.

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/1bd05dde94fd1895. Report an issue: GitHub.