srbhr/Resume-Matcher · warning · HTTPException

Empty job description

Error message

Empty job description

What it means

A 400 Bad Request from upload_job_descriptions raised when an individual entry in job_descriptions is empty or whitespace-only. Unlike error 102 (whole list missing), this fires per-item inside the loop before the job is stored.

Source

Thrown at apps/backend/app/routers/jobs.py:24

from app.schemas import JobUploadRequest, JobUploadResponse

router = APIRouter(prefix="/jobs", tags=["Jobs"])


@router.post("/upload", response_model=JobUploadResponse)
async def upload_job_descriptions(request: JobUploadRequest) -> JobUploadResponse:
    """Upload one or more job descriptions.

    Stores the raw text for later use in resume tailoring.
    Returns an array of job_ids corresponding to the input array.
    """
    if not request.job_descriptions:
        raise HTTPException(status_code=400, detail="No job descriptions provided")

    job_ids = []
    for jd in request.job_descriptions:
        if not jd.strip():
            raise HTTPException(status_code=400, detail="Empty job description")

        job = await db.create_job(
            content=jd.strip(),
            resume_id=request.resume_id,
        )
        job_ids.append(job["job_id"])

    return JobUploadResponse(
        message="data successfully processed",
        job_id=job_ids,
        request={
            "job_descriptions": request.job_descriptions,
            "resume_id": request.resume_id,
        },
    )


@router.get("/{job_id}")

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Trim and filter out empty strings from job_descriptions before uploading
  2. Fix the client-side split logic to drop blank segments (split on /\n\s*\n/ and filter)
  3. If the backend contract should tolerate blanks, sanitize server-side or document the requirement

Example fix

// before
const jds = pasted.split('\n---\n');
await api.post('/jobs/upload', { job_descriptions: jds });
// after
const jds = pasted.split(/\n\s*---\s*\n/).map(s => s.trim()).filter(Boolean);
await api.post('/jobs/upload', { job_descriptions: jds });
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeJobDescriptions(texts) {
  const cleaned = texts.map(t => String(t).trim()).filter(t => t.length > 0);
  if (cleaned.length !== texts.length) console.warn('Dropped empty job description entries');
  return cleaned;
}

Type guard

function allNonEmptyStrings(arr) {
  return Array.isArray(arr) && arr.length > 0 && arr.every(s => typeof s === 'string' && s.trim().length > 0);
}

Try / catch

try {
  await api.post('/jobs/upload', { job_descriptions: jds });
} catch (e) {
  if (e.response?.status === 400 && e.response.data?.detail === 'Empty job description') {
    jds = sanitizeJobDescriptions(jds); // then retry
  } else throw e;
}

Prevention

When it happens

Trigger: A job_descriptions array containing '' or ' ' entries, typically from splitting pasted text on blank lines or extra newlines; a UI allowing an empty job slot to be submitted.

Common situations: User pastes multiple job descriptions separated by blank lines and the client splits naively; trailing separators produce an empty final element; whitespace-only paste from a PDF copy.

Related errors


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