Resolved

Pydantic V2 migration fails with 58.6 percent validator deprecation errors

Python
Pydantic
Backend
Validation
Migration
Testing
Configuration
DevOps

Migration from Pydantic V1 to V2 resulted in widespread validation errors due to deprecated validator syntax and stricter type coercion, particularly affecting environment variables and cross-field validations. Systematic refactoring reduced errors by 78% and improved test pass rates from 25.7% to 60.2%.

Issue

The migration from Pydantic V1 to V2 introduced 112 validation errors (58.6% of total), primarily due to:

  1. Deprecated validator syntax: @validator decorators were replaced with @field_validator and @model_validator(mode='after').
  2. Strict type coercion: Empty environment variables (e.g., CHROMA_PORT=) now trigger ValidationError instead of silently defaulting to None.
  3. Cross-field validation changes: The values parameter in validators was removed, requiring updates to validation logic.
  4. Configuration system overhaul: The class Config pattern was replaced with model_config = ConfigDict(...) syntax.

Culprit

Validator Syntax Changes

Pydantic V2 introduced breaking changes to the validation system:

  • Field validators: Required @field_validator with @classmethod decorator and explicit type hints.
  • Cross-field validation: Moved from @validator to @model_validator(mode='after') for post-validation checks.
  • Removed values parameter: Cross-field validation logic needed restructuring to access other fields.

Environment Variable Handling

Pydantic V2 enforces stricter type coercion, rejecting empty strings in environment variables. For example:

  • Empty strings (CHROMA_PORT=) now cause ValidationError instead of defaulting to None.
  • Fields expecting integers must explicitly handle None or omit empty variables from configuration files.

Configuration System Overhaul

The class Config pattern was deprecated in favor of ConfigDict:

  • json_schema_extra and other configuration attributes must now be defined within model_config.

Solution

Validator Migration Strategy

  1. Field validators: Replaced @validator with @field_validator and added @classmethod and type hints.
  2. Cross-field validation: Used @model_validator(mode='after') to access all fields after initialization.
  3. Type safety: Added explicit type hints and validation logic for environment variables.

Environment Variable Fixes

  • Best practice: Remove empty variables from .env files entirely.
  • Optional fields: Use Optional[int] with explicit default handling.
  • Documentation: Clearly document default values in configuration examples.

Configuration Migration

  • Replaced class Config with model_config = ConfigDict(...) syntax.

Migration Workflow

  • Incremental testing: Monitor test pass rates (target: >50%).
  • Systematic checklist: Track validator replacements, configuration updates, and environment variable fixes.
  • Dependency audit: Ensure required packages (e.g., tree-sitter) are installed.

Results

  • Error reduction: 78% decrease in validation errors.
  • Test pass rate: Improved from 25.7% to 60.2% (+135%).
  • Migration time: ~1.5 hours per file (6 files total).
  • New tests passing: 66 additional validation tests validated.
  • Performance: Test runtime maintained at ~8 seconds per iteration.