srbhr/Resume-Matcher · error · Error
Resume preview data is invalid.
Error message
Resume preview data is invalid.
What it means
buildConfirmPayload throws this when result.data.resume_preview is missing, not an object, or an array. resume_preview is the AI-generated improved resume returned by the improve.preview flow; the page requires a plain object before it can be validated further and cast to ResumeData. The check exists because the LLM response may be malformed or the field may be absent, and the payload would otherwise send garbage to improve.confirm.
Source
Thrown at apps/frontend/app/(default)/tailor/page.tsx:130
};
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:
result.data.improvements?.map((item) => ({
suggestion: item.suggestion,
lineNumber: typeof item.lineNumber === 'number' ? item.lineNumber : null,
})) ?? [],View on GitHub (pinned to 116f9cc3b0)
Solutions
- Regenerate the improved preview (re-run the improve flow) so the backend returns a valid resume_preview object.
- Log the full ImprovedResult to inspect what shape resume_preview actually arrived in (string vs object vs array).
- If the backend returns it as a JSON string, JSON.parse it before the check (or fix the backend serializer).
- Check backend version/compatibility: upgrade or fix the /improve/preview endpoint so it always emits resume_preview as an object.
Example fix
// before
const resumePreview = result.data.resume_preview;
if (!resumePreview || typeof resumePreview !== 'object' || Array.isArray(resumePreview)) {
throw new Error('Resume preview data is invalid.');
}
// after
let raw = result.data.resume_preview;
if (typeof raw === 'string') {
try { raw = JSON.parse(raw); } catch { raw = null; }
}
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
throw new Error('Resume preview data is invalid.');
}
const resumePreview = raw; Defensive patterns
Strategy: validation
Validate before calling
function isValidResumePreview(v: unknown): boolean {
return (
!!v &&
typeof v === 'object' &&
!Array.isArray(v) &&
Object.keys(v as Record<string, unknown>).length > 0
);
}
// run before calling buildConfirmPayload / confirmAndNavigate Type guard
function isResumePreview(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
await confirmAndNavigate(result);
} catch (err) {
if (err instanceof Error && err.message === 'Resume preview data is invalid.') {
setModalError('The generated preview was malformed — regenerate and try again.');
return;
}
throw err;
} Prevention
- Validate the API response shape right after improve.preview returns, before showing the diff modal.
- Log/inspect result.data when the LLM output looks odd; check whether resume_preview arrived as a JSON string.
- Keep backend serialization and frontend ResumeData types in sync (camelCase keys).
- Add a fixture test that feeds a result without resume_preview and asserts the error path.
When it happens
Trigger: Confirming an improved result where result.data.resume_preview is undefined/null (backend omitted the field), is a JSON string instead of a parsed object, is an array, or the ImprovedResult was deserialized from a truncated/failed API response.
Common situations: LLM providers returning malformed JSON that the backend passes through partially; an older backend version not producing resume_preview; a proxy/response interceptor wrapping or stringifying the data field; tests feeding hand-built fixtures without resume_preview.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Resume ID is required.
- Original personalInfo is not a dict: {type(original_info).__
- Improved personalInfo is not a dict: {type(improved_info).__
- 'original' may be a list only for the reorder action
- ${message = data.detail or Failed to update LLM config (stat
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/60186ddf4f6a8c0b.
Report an issue: GitHub.