This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: fastapi-pydantic-v2-nonblocking-validator-guardrail

FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant

Pydantic V2 validators execute synchronously during HTTP payload deserialization before the route handler is invoked. Performing synchronous I/O, network calls, or blocking operations inside field or model validators blocks the asyncio event loop directly or exhausts AnyIO worker threadpools under load, causing catastrophic request queuing and API starvation.

Prohibited Anti-Pattern: Performing Synchronous Blocking I/O or Heavy Compute Inside Pydantic V2 Validators

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant - Pydantic V2 validators execute synchronously during HTTP payload deserialization before the route handler is invoked. Performing synchronous I/O, network calls, or blocking operations inside field or model validators blocks the asyncio event loop directly or exhausts AnyIO worker threadpools under load, causing catastrophic request queuing and API starvation.
globs: app/**/*.py, src/**/*.py, api/**/*.py
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/fastapi-pydantic-v2-nonblocking-validator-guardrail"
---

# FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Performing Synchronous Blocking I/O or Heavy Compute Inside Pydantic V2 Validators

## System Constraints
You are a Principal Backend Architect enforcing strict asyncio and threadpool concurrency safety across FastAPI and Pydantic V2 codebases. Mandate that all Pydantic validators remain strictly pure, non-blocking, and deterministic in-memory operations. Strictly prohibit synchronous network calls, filesystem I/O, database interactions, or blocking sleep statements within Pydantic schema models. Enforce the separation of schema validation from asynchronous business invariant verification via FastAPI dependency injection.

## Strict Guidelines
- Engineers MUST ALWAYS keep Pydantic V2 `@field_validator` and `@model_validator` methods strictly pure, CPU-bound, deterministic, and confined to in-memory structural validation.
- Engineers MUST NOT invoke blocking I/O (e.g., `requests`, synchronous database drivers, synchronous file system access, or `time.sleep`) inside Pydantic schemas or validators.
- Services MUST delegate all asynchronous external validations (e.g., tenant existence, email uniqueness, external auth checks) to FastAPI `Depends` dependencies or domain service layers.
- Components NEVER bridge synchronous validation to asynchronous operations by calling `asyncio.run()` or forcing synchronous event loop evaluation inside Pydantic validation hooks.
- Code SHOULD return RFC-7807 compliant HTTP 422 Unprocessable Entity for Pydantic structural validation failures, and HTTP 400/409/422 domain exceptions from asynchronous dependency layers.

## Bad vs Good Implementations
### Database Existence Check in Pydantic Validator vs. FastAPI Async Dependency

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Pydantic V2 deserialization is synchronous and executed directly within FastAPI's request evaluation cycle. Executing synchronous database queries inside `@field_validator` blocks the single-threaded asyncio event loop for every incoming request, completely neutralizing FastAPI's asynchronous concurrency model and causing extreme AnyIO thread contention.
```python
from pydantic import BaseModel, field_validator
import requests
from sqlalchemy.orm import Session
from app.db import sync_engine

class UserRegistrationRequest(BaseModel):
    username: str
    tenant_id: str

    @field_validator('tenant_id')
    @classmethod
    def validate_tenant_exists(cls, value: str) -> str:
        # CRITICAL ANTI-PATTERN: Synchronous DB/HTTP I/O inside Pydantic validator
        # Blocks the main asyncio event loop thread during JSON deserialization
        with Session(sync_engine) as session:
            tenant = session.execute(
                'SELECT id FROM tenants WHERE id = :id', {'id': value}
            ).scalar_one_or_none()
            if not tenant:
                raise ValueError('Tenant does not exist')
        return value
```

#### Production Standard (Correct)
> **Standard**: The Pydantic model is restricted to pure, CPU-bound structural constraints (UUID format, string boundaries). Database validation is decoupled and moved to an asynchronous FastAPI dependency (`validate_tenant_exists`) utilizing an non-blocking `AsyncSession`, ensuring the event loop remains completely unblocked.
```python
from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy.ext.asyncio import AsyncSession
from app.db import get_async_session
from app.models import Tenant

class UserRegistrationRequest(BaseModel):
    model_config = ConfigDict(strict=True, frozen=True)
    
    # Pure, deterministic, in-memory structural validation only
    username: str = Field(min_length=3, max_length=50, pattern=r'^[a-zA-Z0-9_-]+$')
    tenant_id: UUID

async def validate_tenant_exists(
    payload: UserRegistrationRequest,
    session: Annotated[AsyncSession, Depends(get_async_session)],
) -> UserRegistrationRequest:
    # Invariant: I/O and external checks are handled asynchronously in FastAPI dependencies
    tenant = await session.get(Tenant, payload.tenant_id)
    if not tenant:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f'Tenant {payload.tenant_id} not found',
        )
    return payload

router = APIRouter()

@router.post('/register', status_code=status.HTTP_201_CREATED)
async def register_user(
    user_data: Annotated[UserRegistrationRequest, Depends(validate_tenant_exists)],
) -> dict[str, str]:
    return {'status': 'registered', 'username': user_data.username}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant

FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant defines an industrial-grade behavioral standard for backend engineering. Pydantic V2 validators execute synchronously during HTTP payload deserialization before the route handler is invoked. Performing synchronous I/O, network calls, or blocking operations inside field or model validators blocks the asyncio event loop directly or exhausts AnyIO worker threadpools under load, causing catastrophic request queuing and API starvation. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Performing Synchronous Blocking I/O or Heavy Compute Inside Pydantic V2 Validators Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftPerforming Synchronous Blocking I/O or Heavy Compute Inside Pydantic V2 ValidatorsCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS keep Pydantic V2 `@field_validator` and `@model_validator` methods strictly pure, CPU-bound, deterministic, and confined to in-memory structural validation.

Engineers MUST ALWAYS keep Pydantic V2 `@field_validator` and `@model_validator` methods strictly pure, CPU-bound, deterministic, and confined to in-memory structural validation.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT invoke blocking I/O (e.g., `requests`, synchronous database drivers, synchronous file system access, or `time.sleep`) inside Pydantic schemas or validators.

Engineers MUST NOT invoke blocking I/O (e.g., `requests`, synchronous database drivers, synchronous file system access, or `time.sleep`) inside Pydantic schemas or validators.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Services MUST delegate all asynchronous external validations (e.g., tenant existence, email uniqueness, external auth checks) to FastAPI `Depends` dependencies or domain service layers.

Services MUST delegate all asynchronous external validations (e.g., tenant existence, email uniqueness, external auth checks) to FastAPI `Depends` dependencies or domain service layers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Components NEVER bridge synchronous validation to asynchronous operations by calling `asyncio.run()` or forcing synchronous event loop evaluation inside Pydantic validation hooks.

Components NEVER bridge synchronous validation to asynchronous operations by calling `asyncio.run()` or forcing synchronous event loop evaluation inside Pydantic validation hooks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Code SHOULD return RFC-7807 compliant HTTP 422 Unprocessable Entity for Pydantic structural validation failures, and HTTP 400/409/422 domain exceptions from asynchronous dependency layers.

Code SHOULD return RFC-7807 compliant HTTP 422 Unprocessable Entity for Pydantic structural validation failures, and HTTP 400/409/422 domain exceptions from asynchronous dependency layers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is FastAPI & Pydantic V2 Non-Blocking Event-Loop Validator Invariant critical for AI coding assistants?

Pydantic V2 validators execute synchronously during HTTP payload deserialization before the route handler is invoked. Performing synchronous I/O, network calls, or blocking operations inside field or model validators blocks the asyncio event loop directly or exhausts AnyIO worker threadpools under load, causing catastrophic request queuing and API starvation. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Performing Synchronous Blocking I/O or Heavy Compute Inside Pydantic V2 Validators) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

FastAPI