affaan-m/ECC · warning · ValueError

Invalid email: {self.email}

Error message

Invalid email: {self.email}

What it means

A ValueError raised in User.__post_init__ when the email field does not contain an '@' character. It is a coarse format check executed automatically by the dataclass right after construction. The check only verifies presence of '@', not full RFC 5322 validity.

Source

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

user = User(
    id="123",
    name="Alice",
    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

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Validate email format at the input/parsing boundary (e.g. with a regex or email_validator library) before constructing the dataclass.
  2. Strip whitespace from the email before assignment.
  3. Replace the '@-in-string' heuristic with a proper validator (pydantic.EmailStr or the email_validator package).
  4. Make the dataclass field accept Optional[str] if None is legitimately possible, and validate explicitly.

Example fix

# before
if "@" not in self.email:
    raise ValueError(f"Invalid email: {self.email}")

# after: use a real email validator
from email_validator import validate_email, EmailNotValidError
try:
    self.email = validate_email(self.email, check_deliverability=False).normalized
except EmailNotValidError as e:
    raise ValueError(f"Invalid email: {self.email}") from e
Defensive patterns

Strategy: validation

Validate before calling

import re
EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
def is_plausible_email(s: str) -> bool:
    return isinstance(s, str) and bool(EMAIL_RE.match(s.strip()))

if not is_plausible_email(email):
    raise ValueError(f"Invalid email: {email!r}")

Type guard

def is_non_empty_str(v) -> bool:
    return isinstance(v, str) and v.strip() != ""

Try / catch

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

Prevention

When it happens

Trigger: Constructing User(email=..., age=...) with an email missing '@', an empty string, or None being coerced to the string 'None'. __post_init__ runs immediately after dataclass field assignment.

Common situations: Form input not trimmed/validated before being passed to the dataclass; CSV import where the email column is blank; None passed because an upstream field was optional but the dataclass field is typed str.

Related errors


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