feder-cr/Jobs_Applier_AI_Agent_AIHawk · error · AttributeError

AttributeError in Education: {e}

Error message

AttributeError in Education: {e}

What it means

An AttributeError escaped while processing one education entry — usually because `edu` is not a dict (e.g. a string or None from malformed JSON) so edu.get(...) fails, or a nested value expected to be an object is a scalar. The chained original exception names the attribute.

Source

Thrown at src/resume_schemas/resume.py:155

        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
                )
                education_list.append(education)
            except KeyError as e:
                raise KeyError(f"Missing field in education details: {e}") from e
            except TypeError as e:
                raise TypeError(f"Invalid data for Education: {e}") from e
            except AttributeError as e:
                raise AttributeError(f"AttributeError in Education: {e}") from e
            except Exception as e:
                raise Exception(f"Unexpected error in Education processing: {e}") from e
        return education_list

    def _process_experience_details(self, data: List[Dict[str, Any]]) -> List[ExperienceDetails]:
        experience_list = []
        for exp in data:
            try:
                key_responsibilities = [
                    Responsibility(description=list(resp.values())[0])
                    for resp in exp.get('key_responsibilities', [])
                ]
                skills_acquired = [str(skill) for skill in exp.get('skills_acquired', [])]
                experience = ExperienceDetails(
                    position=exp['position'],
                    company=exp['company'],
                    employment_period=exp['employment_period'],
                    location=exp['location'],

View on GitHub (pinned to 79155b52fa)

Solutions

  1. Read e.__cause__ to identify the offending object type.
  2. Filter/normalize the list first: entries = [e for e in data if isinstance(e, dict)].
  3. Wrap per-entry handling so one bad entry doesn't abort the whole resume (skip-and-log instead of raise).

Example fix

// before
for edu in data:
    exams = [Exam(name=k, grade=v) for k, v in edu.get('exam', {}).items()]

# after
for edu in data:
    if not isinstance(edu, dict):
        logger.warning('skipping non-dict education entry: %r', edu)
        continue
    ...
Defensive patterns

Strategy: type-guard

Validate before calling

data = [e for e in data if isinstance(e, dict)]
# optionally log dropped entries

Type guard

def all_dicts(seq: Any) -> TypeGuard[list[dict]]:
    return isinstance(seq, list) and all(isinstance(e, dict) for e in seq)

Try / catch

try:
    edu_list = _process_education_details(data)
except AttributeError as e:
    logger.warning("malformed education entry (%s); skipping", e)
    edu_list = [ ]  # or partial results

Prevention

When it happens

Trigger: data containing education entries that are strings/None: for edu in ['BSc Computer Science', None] → 'str' object has no attribute 'get'.

Common situations: Heterogeneous extraction output where some entries are plain text instead of structured dicts; null entries in sparse resumes.

Related errors


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