Skip to content

Fix: JSON import silently drops all experience achievements#10

Closed
gibbenergy wants to merge 2 commits intomainfrom
fix/json-achievements-parsing
Closed

Fix: JSON import silently drops all experience achievements#10
gibbenergy wants to merge 2 commits intomainfrom
fix/json-achievements-parsing

Conversation

@gibbenergy
Copy link
Owner

Bug Report (Beta User)

A beta user reported that after uploading a JSON resume file, the experience section was missing all achievement bullet points. The descriptions loaded correctly, but every achievement/bullet point across all experience entries was silently dropped.

Root Cause

ResumeLoader._convert_to_form_format() calls SchemaEngine.extract_list_fields() on the experience data before processing the achievements field. Since the EXPERIENCE schema defines achievements as type: str, the schema engine converts the Python list (e.g. ["bullet1", "bullet2"]) into its string representation ("['bullet1', 'bullet2']").

The subsequent check isinstance(achievements, list) then evaluates to False, and all achievements are set to an empty string:

# BEFORE (bug)
experience_data = SchemaEngine.extract_list_fields(data.get('experience', []), ResumeSchema.EXPERIENCE)
for exp in experience_data:
    achievements = exp.get('achievements', [])  # This is now a STRING, not a list
    if isinstance(achievements, list):           # False!
        exp['achievements'] = '\n'.join(...)
    else:
        exp['achievements'] = ''                 # All bullets lost

Fix

Capture the raw achievements lists from the JSON data before schema extraction converts them, then re-inject after processing:

# AFTER (fix)
raw_experience = data.get('experience', [])
raw_achievements = []
for exp in raw_experience:
    achievements = exp.get('achievements', [])
    raw_achievements.append(achievements if isinstance(achievements, list) else [])

experience_data = SchemaEngine.extract_list_fields(raw_experience, ResumeSchema.EXPERIENCE)
for i, exp in enumerate(experience_data):
    achievements = raw_achievements[i] if i < len(raw_achievements) else []
    exp['achievements'] = '\n'.join([f"- {item}" for item in achievements if item])

Test Plan

  • Added 5 regression tests in tests/backend/unit/test_resume_loader.py
    • Achievements are preserved in form output (correct count per entry)
    • Achievement content is not truncated
    • Achievements formatted as - bullet lines
    • Empty achievements list handled gracefully
    • Missing achievements key handled gracefully
  • All 5 tests pass
  • Verified full round-trip: JSON upload -> form values -> resume data returns all 16 bullets across 4 experience entries

🤖 Generated with Claude Code

gibbenergy and others added 2 commits February 11, 2026 19:23
SchemaEngine.extract_list_fields() converts the achievements array to a
Python string representation because the EXPERIENCE schema defines
achievements as type: str. The subsequent isinstance() check then fails,
causing all bullet points to be silently dropped.

Fix by capturing the raw achievements lists from the JSON data before
schema extraction, then re-injecting them after processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5 tests covering the bug where achievements bullet points were silently
dropped during JSON resume import:
- Achievements are preserved in form output
- Achievement content is not truncated
- Achievements formatted as bullet list
- Empty achievements handled gracefully
- Missing achievements key handled gracefully

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gibbenergy gibbenergy closed this Feb 12, 2026
@gibbenergy gibbenergy deleted the fix/json-achievements-parsing branch February 12, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant