Nils
09/16/2025, 12:27 PMInput should be an instance of Date
. The UI properly shows a date picker.Marvin
09/16/2025, 12:27 PMMarvin
09/16/2025, 12:34 PMpendulum.Date
instance, so validation passes.
- In a deployment, the UI serializes inputs over the API (JSON). Pydantic (used by Prefect 3.x for parameter validation) can parse strings into built-in datetime.date
, but it does not know how to parse into pendulum.Date
unless you provide custom validators. For arbitrary/custom classes, Pydantic generally expects an instance to already be of that type. Hence the error “Input should be an instance of Date.”
Recommended fix
- Annotate your parameter as a standard datetime.date
(or datetime.datetime
), then convert to Pendulum inside the flow if you need it.
Example
from datetime import date
import pendulum
from prefect import flow
@flow
def my_flow(run_date: date):
# Convert if you need a Pendulum date
p_date = pendulum.date(run_date.year, run_date.month, run_date.day)
...
If you must keep a Pendulum type
- Wrap the parameter in a Pydantic model with a validator that parses strings into pendulum.Date
, and allow arbitrary types. Note: this will present as an object in the UI instead of a single date field.
from datetime import date as pydate
import pendulum
from pydantic import BaseModel, ConfigDict, field_validator
from prefect import flow
class Params(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
run_date: pendulum.Date
@field_validator("run_date", mode="before")
def parse_run_date(cls, v):
if isinstance(v, str):
# Accept ISO strings from the UI
return pendulum.parse(v).date()
if isinstance(v, pydate):
return pendulum.date(v.year, v.month, v.day)
return v
@flow
def my_flow(params: Params):
p_date = params.run_date
...
Why this is the case
- Prefect 3.x validates flow parameters using Pydantic. Values sent from the UI/API are JSON-encoded; Pydantic has built-in parsing for stdlib datetime/date, but not for pendulum.Date
without custom validators. See source references:
- Flows and parameter handling: prefect/src/prefect/flows.py
- Serialization helpers: prefect/src/prefect/serializers.py
If you share your flow signature and how you’re invoking it locally vs. in the UI, I can confirm the minimal change. But in most cases, switching the annotation to datetime.date
and converting to Pendulum inside the flow is the simplest and most reliable approach.