Skip to main content

Overview

Pydantic v2 is used for input and output validation. The params and secure_params run() arguments and its return type should inherit from Pydantic BaseModel. You can use any type, constraint, or validator Pydantic supports. Input validation errors are raised before your run() function executes; output validation errors are raised after it returns. Pydantic validation errors, like any exceptions raised by run(), are reported as run failures.
Don’t catch WorkflowError at the top level of your run() function unless you plan to return a valid Result. Swallowing errors silently can lead to missing or incorrect results.

Example

class Result(BaseModel):
    customer_id: str = Field(min_length=8, max_length=16)
    name: str

# This will raise a validation error if customer_id is too short
return Result(customer_id="ABC", name="Jane")
If your Result validation fails, the run reports a failure. Make sure your output constraints match what your workflow actually produces.

Field Constraints

Use Pydantic’s Field() constraints liberally on Params and SecureParams — they catch bad input before your workflow starts, saving time and compute.
Use Field() to add validation rules:
from pydantic import BaseModel, Field

class Params(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    post_number: int = Field(gt=0)
    customer_id: str = Field(min_length=8, max_length=16)
ConstraintTypeDescription
min_length / max_lengthstrString length bounds
ge / leint, floatGreater/less than or equal
gt / ltint, floatStrictly greater/less than
defaultanyDefault value if not provided

Special Types

Pydantic’s built-in types work out of the box:
from pydantic import BaseModel, Field, EmailStr, AnyUrl

class Params(BaseModel):
    email: EmailStr
    website: AnyUrl
    name: str = Field(min_length=1, max_length=100)

Optional Fields

Use | None with a default for optional fields:
class Result(BaseModel):
    user_id: str
    phone: str | None = Field(default=None)
    email: EmailStr | None = Field(default=None)

Default Values

class Params(BaseModel):
    url: str = Field(default="https://example.com", min_length=1)
    max_retries: int = Field(default=3, ge=1, le=10)

List Fields

class Params(BaseModel):
    selected_customers: list[str]
    tags: list[str] = Field(default_factory=list)
Add constraints to catch bad input early. A min_length=1 on a required string prevents empty strings from reaching your workflow logic.