srbhr/Resume-Matcher · error · Error
Master resume ID is missing.
Error message
Master resume ID is missing.
What it means
buildConfirmPayload in apps/frontend/app/(default)/tailor/page.tsx throws this when the client-side masterResumeId state is falsy (null/empty) at the moment the user confirms the AI-improved resume preview. masterResumeId is initialized to null and only set from localStorage key 'master_resume_id' in a useEffect; if the key is absent the component redirects to /dashboard, but a confirm click can still race the effect or run with an empty stored value. The guard exists because the confirm payload requires resume_id to link the improved resume back to its master.
Source
Thrown at apps/frontend/app/(default)/tailor/page.tsx:126
if (!cancelled) {
setPromptLoading(false);
}
}
};
loadPromptConfig();
return () => {
cancelled = true;
};
}, []);
const handleTextareaKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') e.stopPropagation();
};
const buildConfirmPayload = (result: ImprovedResult) => {
if (!masterResumeId) {
throw new Error('Master resume ID is missing.');
}
const resumePreview = result.data.resume_preview;
if (!resumePreview || typeof resumePreview !== 'object' || Array.isArray(resumePreview)) {
throw new Error('Resume preview data is invalid.');
}
const previewRecord = resumePreview as unknown as Record<string, unknown>;
if (
!previewRecord.personalInfo ||
typeof previewRecord.personalInfo !== 'object' ||
Array.isArray(previewRecord.personalInfo)
) {
throw new Error('Resume preview data is invalid.');
}
return {
resume_id: masterResumeId,
job_id: result.data.job_id,
improved_data: resumePreview as ResumeData,
improvements:View on GitHub (pinned to 116f9cc3b0)
Solutions
- Upload/select a master resume first (via /builder or /dashboard) so 'master_resume_id' exists in localStorage before visiting /tailor.
- Guard the confirm button: disable it (or show the dashboard redirect) until masterResumeId is set.
- In buildConfirmPayload's caller, catch this error and re-run the localStorage check / redirect to /dashboard instead of crashing.
- Clear the site's localStorage or use a normal (non-private) window if storage was the cause.
Example fix
// before
const buildConfirmPayload = (result: ImprovedResult) => {
if (!masterResumeId) {
throw new Error('Master resume ID is missing.');
}
...
};
// after
const buildConfirmPayload = (result: ImprovedResult) => {
const storedId = masterResumeId ?? localStorage.getItem('master_resume_id');
if (!storedId) {
router.push('/dashboard');
throw new Error('Master resume ID is missing.');
}
...
}; Defensive patterns
Strategy: try-catch
Validate before calling
function canConfirm(): boolean {
const id = typeof window !== 'undefined' ? localStorage.getItem('master_resume_id') : null;
return Boolean(id);
}
// disable the confirm action until canConfirm() is true Type guard
function hasMasterResumeId(id: string | null): id is string {
return typeof id === 'string' && id.length > 0;
} Try / catch
try {
await confirmAndNavigate(result);
} catch (err) {
if (err instanceof Error && err.message === 'Master resume ID is missing.') {
localStorage.removeItem('master_resume_id');
router.push('/dashboard');
return;
}
throw err;
} Prevention
- Never deep-link to /tailor without first storing 'master_resume_id' via the builder/dashboard flow.
- Render the confirm button only after masterResumeId state is hydrated (non-null).
- Handle the storage/unload events if localStorage can be cleared while the page is open.
- In tests, seed localStorage before mounting and wait for effects before clicking confirm.
When it happens
Trigger: Calling confirmAndNavigate/buildConfirmPayload while masterResumeId is still null: (1) the 'master_resume_id' localStorage key was never set (user navigated straight to /tailor without uploading a resume in /builder), (2) the confirm action fires before the hydration useEffect finishes, (3) localStorage was cleared (private browsing, storage eviction) between mount and confirm.
Common situations: Deep-linking or refreshing /tailor after clearing site data; opening the page in an incognito window where localStorage writes don't persist; a stale tab where another tab's 'reset database' cleared the ID; tests clicking confirm before effects run.
Related errors
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/6a59e0da48ebb291.
Report an issue: GitHub.