affaan-m/ECC · error · HTTPException

Email already registered

Error message

Email already registered

What it means

Illustrative handler from the fastapi-patterns skill: UserService raised DuplicateUserError while creating/updating a user, which the router translates into an HTTP 400 with this detail. The email in the payload already exists in the database.

Solutions

  1. Enforce uniqueness with a DB constraint in addition to the service check
  2. Return 409 Conflict for duplicate resources
  3. Suggest login/password-reset when the email is already registered
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at skills/fastapi-patterns/SKILL.md:248 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26). Data as JSON: /api/errors/2b2911eb4d84f44e. Report an issue: GitHub.

Appendix: source

Thrown at skills/fastapi-patterns/SKILL.md:248

# app/routers/users.py
from typing import Annotated
from fastapi import APIRouter, HTTPException, Query, status
from fastapi.security import OAuth2PasswordRequestForm

from app.dependencies import ActiveUserDep, DbDep
from app.schemas.user import UserCreate, UserResponse, UserUpdate, UserListResponse
from app.services.user_service import DuplicateUserError, UserService

router = APIRouter()


@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(payload: UserCreate, db: DbDep) -> UserResponse:
    service = UserService(db)
    try:
        return await service.create(payload)
    except DuplicateUserError:
        raise HTTPException(status_code=400, detail="Email already registered")


@router.get("/me", response_model=UserResponse)
async def get_me(current_user: ActiveUserDep) -> UserResponse:
    return current_user


@router.get("/", response_model=UserListResponse)
async def list_users(
    db: DbDep,
    current_user: ActiveUserDep,
    skip: Annotated[int, Query(ge=0)] = 0,
    limit: Annotated[int, Query(ge=1, le=100)] = 20,
) -> UserListResponse:
    service = UserService(db)
    users, total = await service.list(skip=skip, limit=limit)
    return UserListResponse(total=total, items=users)

View on GitHub (pinned to d8409a4b08)