affaan-m/ECC · warning · ValueError

Invalid age: {self.age}

Error message

Invalid age: {self.age}

What it means

A ValueError raised in User.__post_init__ when the age field is outside the inclusive range [0, 150]. It enforces a sanity bound on age immediately after the dataclass is constructed. Both negative ages and implausibly large values trip the check.

Source

Thrown at skills/python-patterns/SKILL.md:349

    email="alice@example.com"
)
```

### Data Classes with Validation

```python
@dataclass
class User:
    email: str
    age: int

    def __post_init__(self):
        # Validate email format
        if "@" not in self.email:
            raise ValueError(f"Invalid email: {self.email}")
        # Validate age range
        if self.age < 0 or self.age > 150:
            raise ValueError(f"Invalid age: {self.age}")
```

### Named Tuples

```python
from typing import NamedTuple

class Point(NamedTuple):
    """Immutable 2D point."""
    x: float
    y: float

    def distance(self, other: 'Point') -> float:
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

# Usage
p1 = Point(0, 0)
p2 = Point(3, 4)

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Coerce and validate age at the input boundary: int(age) inside a try/except, then range-check.
  2. Use a sentinel like None for unknown age instead of -1, and adjust the field type to Optional[int].
  3. Compute age from birthdate with a tested helper rather than accepting a raw number from the user.
  4. If importing bulk data, log and quarantine rows that fail the range check instead of aborting the batch.

Example fix

# before
if self.age < 0 or self.age > 150:
    raise ValueError(f"Invalid age: {self.age}")

# after: explicit type guard and named bounds
MIN_AGE, MAX_AGE = 0, 150
if not isinstance(self.age, int):
    raise TypeError(f"age must be int, got {type(self.age).__name__}")
if not MIN_AGE <= self.age <= MAX_AGE:
    raise ValueError(f"age {self.age} outside [{MIN_AGE},{MAX_AGE}]")
Defensive patterns

Strategy: validation

Validate before calling

MIN_AGE, MAX_AGE = 0, 150
def is_valid_age(v) -> bool:
    return isinstance(v, int) and not isinstance(v, bool) and MIN_AGE <= v <= MAX_AGE

if not is_valid_age(age):
    raise ValueError(f"Invalid age: {age!r}")

Type guard

from numbers import Integral
def is_int_in_range(v, lo, hi) -> bool:
    return isinstance(v, Integral) and not isinstance(v, bool) and lo <= v <= hi

Try / catch

try:
    user = User(email=email, age=age)
except ValueError as e:
    return respond_400(field="age", message=str(e))

Prevention

When it happens

Trigger: Constructing User(email, age) with age < 0 (e.g. a default sentinel like -1), age > 150 (a typo or wrong unit such as months), or a non-integer that compares incorrectly.

Common situations: CSV/JSON import where age is missing and defaults to -1 or 999; birthdate computed incorrectly producing a negative age; age supplied in months instead of years; a string '42' that happens to compare but later breaks arithmetic.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/3871fa8f4c6379a4. Report an issue: GitHub.