srbhr/Resume-Matcher · error · ValueError
Improved personalInfo is not a dict: {type(improved_info).__
Error message
Improved personalInfo is not a dict: {type(improved_info).__name__} What it means
JSON-008 type guard on the improved side: improved_data.personalInfo must be a dict to allow field-by-field comparison with the original. If it is present but not a dict, the ValueError embeds the actual type name and the confirm endpoint surfaces HTTP 400. This prevents persisting a tailored resume whose identity block has the wrong structure.
Source
Thrown at apps/backend/app/routers/resumes.py:542
) -> None:
if not original_data:
logger.warning(
"Skipping confirm payload validation; structured resume data unavailable."
)
return
original_info = original_data.get("personalInfo")
improved_info = improved_data.get("personalInfo")
# JSON-008: Explicit null checks with clear error messages
if original_info is None:
raise ValueError("Original resume missing personalInfo")
if improved_info is None:
raise ValueError("Improved resume missing personalInfo")
if not isinstance(original_info, dict):
raise ValueError(
f"Original personalInfo is not a dict: {type(original_info).__name__}"
)
if not isinstance(improved_info, dict):
raise ValueError(
f"Improved personalInfo is not a dict: {type(improved_info).__name__}"
)
fields = set(original_info.keys()) | set(improved_info.keys())
mismatches = [
field
for field in sorted(fields)
if _normalize_personal_info_value(original_info.get(field))
!= _normalize_personal_info_value(improved_info.get(field))
]
if mismatches:
raise ValueError(f"personalInfo fields changed: {', '.join(mismatches)}")
async def _generate_auxiliary_messages(
improved_data: dict[str, Any],
job_content: str,
language: str,
enable_cover_letter: bool,View on GitHub (pinned to 116f9cc3b0)
Solutions
- Validate the improved payload shape client-side before calling confirm (personalInfo must be an object)
- Re-run preview and use its improved data verbatim
- If caused by the pipeline, inspect generate_resume_diffs/apply_diffs output for personalInfo path corruption
Example fix
// before: LLM emitted a list
"personalInfo": ["Jane Doe", "jane@example.com"]
// after
"personalInfo": {"name": "Jane Doe", "email": "jane@example.com"} Defensive patterns
Strategy: type-guard
Validate before calling
// client: validate the improved payload before confirm
function validPersonalInfo(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
}
if (!validPersonalInfo(improvedData.personalInfo)) throw new TypeError('personalInfo must be an object'); Type guard
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
await api.post('/resumes/improve/confirm', body);
} catch (e) {
if (e.response?.status === 400) {
const preview = await api.post('/resumes/improve/preview', previewPayload);
// retry using the canonical preview output
}
} Prevention
- Schema-check LLM output shape before submitting confirm (arrays-as-personalInfo is the classic drift)
- Never hand-assemble confirm bodies in scripts
- Add a JSON-schema assertion on improved_data in your test suite
When it happens
Trigger: POST /resumes/improve/confirm where the improved payload's personalInfo is a non-dict (string, list, etc.) — typically a client-sent malformed confirm body, or an LLM/diff step emitting personalInfo as an array of strings.
Common situations: Hand-crafted confirm requests in scripts/tests; LLM JSON-mode output shape drift; automated tooling posting transformed data without schema validation.
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
- Original personalInfo is not a dict: {type(original_info).__
- Resume preview data is invalid.
- Original resume missing personalInfo
- Improved resume missing personalInfo
- personalInfo fields changed: {', '.join(mismatches)}
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/cc126d5d8730c2a0.
Report an issue: GitHub.