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

  1. Upload/select a master resume first (via /builder or /dashboard) so 'master_resume_id' exists in localStorage before visiting /tailor.
  2. Guard the confirm button: disable it (or show the dashboard redirect) until masterResumeId is set.
  3. In buildConfirmPayload's caller, catch this error and re-run the localStorage check / redirect to /dashboard instead of crashing.
  4. 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

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.