Jeff Garcia
08/14/2025, 8:07 PMdatetime.today().strftime("%Y-%m-%d")
, but this does not work how I expected it to work. I think what's happening is the date of the initial change to the deployment itself is the date showing up. But subsequent attempts to run the deployment are showing that same deployment update date instead of today's date like I'd expect.Marvin
08/14/2025, 8:07 PMMarvin
08/14/2025, 8:10 PMdatetime.today().strftime(...)
is computed once and baked into the default.
- In Prefect 3.x, deployments snapshot those defaults at deploy time. So your “today” becomes “the day I deployed” forever after, unless you pass a value when you run.
Fixes
1) Use a sentinel default and compute at run time
from datetime import date
from prefect import flow
@flow
def my_flow(run_date: str | None = None):
run_date = run_date or date.today().isoformat()
# do work
2) If you want “today” to be the schedule’s day (not the worker’s clock), use the scheduled start time
from datetime import datetime, timezone
from prefect import flow
from prefect.runtime import flow_run
@flow
def my_flow(run_date: str | None = None):
if not run_date:
ts = flow_run.scheduled_start_time # may be None if triggered ad-hoc
if ts is None:
ts = datetime.now(timezone.utc)
run_date = ts.date().isoformat()
# do work
Notes
- Prefer ISO strings for parameters; they’re JSON friendly.
- Avoid naive datetime.today()
. Use UTC where possible.
- If you really want a new default, redeploy or pass the param when triggering a run.
Related docs
- Schedules in Prefect 3.x: Schedules concept
- Deployment versioning (why snapshots stick): Deployment versioning blog
If you share your flow signature, I can rewrite it with a safe pattern in about the time it takes a worker to yawn.Jeff Garcia
08/14/2025, 8:12 PMJeff Garcia
08/14/2025, 8:23 PM