srbhr/Resume-Matcher · error · Error
Resume ID is required.
Error message
Resume ID is required.
What it means
normalizeResumeId in apps/frontend/lib/api/resume.ts throws this synchronous Error when the supplied resumeId is empty or contains only whitespace after trimming. It is a client-side input guard used before every resume API call in this module, preventing pointless network requests with an invalid path parameter.
Source
Thrown at apps/frontend/lib/api/resume.ts:99
resume_id: string;
processing_status: 'pending' | 'processing' | 'ready' | 'failed';
is_master: boolean;
}
interface ImproveResumeConfirmRequest {
resume_id: string;
job_id: string;
improved_data: ResumeData;
improvements: Array<{
suggestion: string;
lineNumber?: number | null;
}>;
}
function normalizeResumeId(resumeId: string): string {
const normalized = resumeId.trim();
if (!normalized) {
throw new Error('Resume ID is required.');
}
return normalized;
}
export interface ResumeListItem {
resume_id: string;
filename: string | null;
is_master: boolean;
parent_id: string | null;
processing_status: 'pending' | 'processing' | 'ready' | 'failed';
created_at: string;
updated_at: string;
title?: string | null;
// Optional lightweight snippet of associated job description (populated client-side)
jobSnippet?: string;
}
async function postImprove(View on GitHub (pinned to 116f9cc3b0)
Solutions
- Check where the resumeId comes from (router params, query string, state) and confirm it is populated before invoking the API.
- Gate the API call behind a loading/ready flag so it only runs once the ID is available.
- Trim and truthiness-check the ID at the call site and show a user-facing 'resume not selected' state instead of calling the API.
- Fix the data source that produced the empty ID (missing route param, empty localStorage entry).
Example fix
// before
useEffect(() => {
getResume(resumeId).then(setResume);
}, [resumeId]);
// after
useEffect(() => {
if (!resumeId?.trim()) return;
getResume(resumeId).then(setResume);
}, [resumeId]); Defensive patterns
Strategy: validation
Validate before calling
const id = (resumeId ?? '').trim();
if (!id) {
// skip the API call and render an empty/redirect state
return null;
} Type guard
function isValidResumeId(v: unknown): v is string {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
const resume = await getResume(resumeId);
} catch (e) {
if (e instanceof Error && e.message === 'Resume ID is required.') {
showError('No resume selected. Please choose a resume first.');
return;
}
throw e;
} Prevention
- Never call resume APIs until the router/query param for the resume ID has resolved.
- Treat empty IDs at the UI layer (disabled buttons, redirects) instead of letting the API layer throw.
- Sanitize IDs read from localStorage/URL: trim and check truthiness before use.
When it happens
Trigger: Calling any resume API function (getResume, improveResume, uploadJobDescriptions, etc.) with resumeId = '' , ' ', or an undefined/null value coerced to an empty string — typically because state had not loaded yet or a route param was missing.
Common situations: A React component renders and fires the API call before the resume ID is fetched from the router/query; a deep link is missing the id query parameter; localStorage held an empty value after a cleared session; copy-paste dropped the ID.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Resume preview data is invalid.
- ${message = data.detail or Failed to update LLM config (stat
- ${data.detail || Failed to update feature config (status ${r
- ${data.detail || Failed to update language config (status ${
- ${data.detail || Failed to update prompt config (status ${re
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/f7092b8377e9eac6.
Report an issue: GitHub.