feder-cr/Jobs_Applier_AI_Agent_AIHawk · error · TypeError

Invalid data for PersonalInformation: {e}

Error message

Invalid data for PersonalInformation: {e}

What it means

Raised when constructing the PersonalInformation dataclass with keyword arguments that don't match its __init__ signature — e.g. unexpected keys, missing required fields, or wrong types. Python's dataclass __init__ (or a validating __post_init__) raises TypeError, which this wrapper re-raises with a descriptive prefix. It almost always means the input dict (often parsed JSON) doesn't conform to the resume schema.

Source

Thrown at src/resume_schemas/resume.py:129

            if 'education_details' in data:
                for ed in data['education_details']:
                    if 'exam' in ed:
                        ed['exam'] = self.normalize_exam_format(ed['exam'])

            # Create an instance of Resume from the parsed data
            super().__init__(**data)
        except yaml.YAMLError as e:
            raise ValueError("Error parsing YAML file.") from e
        except Exception as e:
            raise Exception(f"Unexpected error while parsing YAML: {e}") from e


    def _process_personal_information(self, data: Dict[str, Any]) -> PersonalInformation:
        try:
            return PersonalInformation(**data)
        except TypeError as e:
            raise TypeError(f"Invalid data for PersonalInformation: {e}") from e
        except AttributeError as e:
            raise AttributeError(f"AttributeError in PersonalInformation: {e}") from e
        except Exception as e:
            raise Exception(f"Unexpected error in PersonalInformation processing: {e}") from e

    def _process_education_details(self, data: List[Dict[str, Any]]) -> List[EducationDetails]:
        education_list = []
        for edu in data:
            try:
                exams = [Exam(name=k, grade=v) for k, v in edu.get('exam', {}).items()]
                education = EducationDetails(
                    education_level=edu.get('education_level'),
                    institution=edu.get('institution'),
                    field_of_study=edu.get('field_of_study'),
                    final_evaluation_grade=edu.get('final_evaluation_grade'),
                    start_date=edu.get('start_date'),
                    year_of_completion=edu.get('year_of_completion'),
                    exam=exams

View on GitHub (pinned to 79155b52fa)

Solutions

  1. Inspect the full TypeError message ({e}) — it names the exact unexpected/missing argument; fix the input dict accordingly.
  2. If extra keys are legitimate, add them as fields to PersonalInformation or filter data through {k: v for k, v in data.items() if k in expected_fields} before construction.
  3. Give the offending fields default values (field: Optional[str] = None) so partial data no longer raises.
  4. Validate the payload with a schema (pydantic/jsonschema) before calling _process_personal_information.

Example fix

// before
pi = PersonalInformation(**data)  # data has extra/missing keys

# after
allowed = {f.name for f in dataclasses.fields(PersonalInformation)}
pi = PersonalInformation(**{k: v for k, v in data.items() if k in allowed})
Defensive patterns

Strategy: validation

Validate before calling

import dataclasses
ALLOWED_PI = {f.name for f in dataclasses.fields(PersonalInformation)}
REQUIRED_PI = {f.name for f in dataclasses.fields(PersonalInformation) if f.default is dataclasses.MISSING and f.default_factory is dataclasses.MISSING}

def validate_personal_information(data):
    if not isinstance(data, dict):
        raise ValueError(f"expected dict, got {type(data).__name__}")
    missing = REQUIRED_PI - data.keys()
    if missing:
        raise ValueError(f"missing required fields: {sorted(missing)}")
    extra = set(data) - ALLOWED_PI
    if extra:
        raise ValueError(f"unexpected fields: {sorted(extra)}")
    return {k: v for k, v in data.items() if k in ALLOWED_PI}

Type guard

from typing import Dict, Any, TypeGuard

def is_personal_information_payload(data: Any) -> TypeGuard[Dict[str, Any]]:
    return isinstance(data, dict) and all(isinstance(k, str) for k in data)

Try / catch

try:
    pi = _process_personal_information(data)
except TypeError as e:
    logger.error("personal information schema mismatch: %s", e)
    # fall back to defaults or skip section
    pi = PersonalInformation()  # only if all fields have defaults
except AttributeError as e:
    logger.error("personal information payload malformed: %s", e)
    raise

Prevention

When it happens

Trigger: Calling the resume parser/constructor with a dict containing keys that are not fields of PersonalInformation, omitting required fields (no defaults), or passing a non-mapping. Typical entry point: _process_personal_information({'name': ..., 'extra_key': ...}).

Common situations: Upstream LLM/JSON extraction produced extra or renamed keys; schema drift after adding/removing dataclass fields; a None passed instead of a dict; version change of the resume schema.

Related errors


AI-assisted analysis of feder-cr/Jobs_Applier_AI_Agent_AIHawk@79155b52fa (2026-08-28). Data as JSON: /api/errors/93e744fb532e59e6. Report an issue: GitHub.