3.9.1 - This hour is a rerun
Released on October 30, 2026 Enhancements ➕➕- Add custom state discovery and filters by @desertaxle in #23490
- Add Run action to the React flows list menu and flow page by @devin-ai-integration[bot] in #23354
- Allow sorting task runs by duration by @nolantonio in #23275
- Allow dismissing the V1 UI sidebar shortcut by @zzstoatzz in #23626
- Enforce duration input minimum by @uinstinct in #23122
- Cache
get_timezones()by @tylerjthomas9 in #23531 - Share orchestration clients across automation actions by @fatih-acar in #23255
- Restore advisory Cloud API compatibility checks by @desertaxle in #23624
- Show plain IDs instead of
UUID(...)reprs in CLI messages by @LuisFigueroaG in #23650 - Align date picker popover to the start instead of center by @uinstinct in #23655
- Prevent state persistence error from failing success flow by @uinstinct in #22745
- Skip unset Pydantic private attributes when rebuilding models in
visit_collectionby @devin-ai-integration[bot] in #23515 - Retry flows that return a failed state when
retriesis configured by @devin-ai-integration[bot] in #23535 - Preserve literal markup and emoji aliases in variable CLI JSON output by @devin-ai-integration[bot] in #23530
- Resolve numeric string dict keys in
get_from_dictby @devin-ai-integration[bot] in #23454 - Begin SQLite write transaction before reading automation buckets by @devin-ai-integration[bot] in #23471
- Fix forked child processes exiting with code 1 because of QueueService at-exit drain by @devin-ai-integration[bot] in #23464
- Serialize context on every
ProcessPoolTaskRunner.submit()by @devin-ai-integration[bot] in #23376 - Schedule
astopon SIGTERM instead of dropping the coroutine by @devin-ai-integration[bot] in #23346 - Keep flows search input focused while filtering by @devin-ai-integration[bot] in #23338
- Keep daily
IntervalSchedulewall-clock time across DST when start is after the change by @devin-ai-integration[bot] in #23205 - Allow the provisioned ECS execution role to create CloudWatch log groups by @Sagargupta16 in #23557
- Fix
GitRepository.pull_code()re-cloning a shallow clone on every new commit by @CassianoE in #23351 - Substitute
apply_valuesplaceholders in a single pass by @devin-ai-integration[bot] in #23494 - Percent-encode path values in
url_forby @devin-ai-integration[bot] in #23493 - Read automation buckets in a single query to avoid refresh race by @devin-ai-integration[bot] in #23604
- Delete every automation with
prefect automation delete --allby @cf3901646 in #23521 - Apply both
any_andnot_any_in flow run state filters by @spicysharkco in #23459 - Fix JSON flow results with
dataorresultkeys reading back wrong by @devin-ai-integration[bot] in #23377 - Preserve deployment concurrency lease ID on forced flow run state changes by @darshjoshi in #23304
- Fix
filter_filesaborting on a directory symlink cycle by @aayushbaluni in #23307 - Preserve cron start bounds in repeated DST hours by @zzstoatzz in #23634
- Recover cron occurrences shifted through DST gaps by @zzstoatzz in #23636
- Exit non-zero from
flow-run executewhen a crash cannot be reported by @devin-ai-integration[bot] in #23393 - Skip repeated cron occurrences during scheduler refills by @zzstoatzz in #23652
- Stop extra cron runs during DST refills on Python 3.11 and 3.12 by @desertaxle in #23672
- Fall back to placeholder for any
jsonable_encodererror inFlow.serialize_parametersby @devin-ai-integration[bot] in #23630 - Fix 500 from flow run list endpoints when a parameter exceeds 64 bits by @DEVJHAWAR11 in #23429
- Reset pause keys when a blocking pause is rescheduled by @devin-ai-integration[bot] in #23399
- Read until final state after terminal event in
wait_for_flow_runby @devin-ai-integration[bot] in #23669 - Display zero and false enum selections in the UI by @ashutosh8021 in #23656
- Publish duration lower bounds only where validation enforces them by @gaker in #23507
- Read metric triggers on metrics this version doesn’t know by @nathandpeterson in #23513
- Fix duplicate retries label in deployments custom run by @uinstinct in #23343
- Show a not-found error from
prefect flow-run inspectfor missing runs by @LuisFigueroaG in #23329 - Show a not-found error from
prefect deployment run --idfor missing deployments by @LuisFigueroaG in #23586 - Show an invalid ID error from
prefect deployment run --idfor malformed IDs by @LuisFigueroaG in #23621 - Show an invalid slug error from
prefect block inspectandblock deletefor extra slashes by @LuisFigueroaG in #23670 - Read every global concurrency limit in
prefect transferby @spicysharkco in #23456 - Add
urlproperty to client-sideReceivedEventby @ethanstoner in #23181 - Prevent incorrect cached task results by preserving DataFrame column order by @uinstinct in #23303
- Raise
ObjectUnsupportedfrom the asynccreate_work_poolwhen the plan doesn’t allow the pool by @LuisFigueroaG in #23610 - Fix task returning another task’s cached results by @uinstinct in #23468
- Make date range span relative instead of absolute by @uinstinct in #23086
- Fix returned failed states being cached as successful task results by @uinstinct in #23523
- Fix date changing when clicking pm in date selector by @uinstinct in #23622
- Fix “use default value” doing nothing in parameter inputs by @uinstinct in #23657
- Make the server compatible with SQLAlchemy 2.1 by @devin-ai-integration[bot] in #23201
- Lock current
prefect-redisandprefect-kubernetesfor the Docker image by @devin-ai-integration[bot] in #23537 - Bump stale integration pins in
uv.lockand keep them current on release by @devin-ai-integration[bot] in #23527 - Upgrade cyclopts to 5.3.2 and keep CLI exit codes and command names by @gaker in #23646
- Refresh the Python and UI dependency lockfiles by @gaker in #23666
- Move the remaining Node 20 pins to Node 22 by @znicholasbrown in #23509
- Update Node to the October 2026 security releases by @znicholasbrown in #23508
- Bump vite from 8.2.2 to 8.3.4 in /ui-v2 by @dependabot[bot] in #23488
- Bump opentelemetry-api from 1.44.0 to 1.45.1 by @dependabot[bot] in #23539
- Bump zod from 4.5.4 to 4.6.7 in /ui-v2 by @dependabot[bot] in #23547
- Bump graphql-core from 3.2.7 to 3.2.12 by @dependabot[bot] in #23542
- Bump pillow from 12.3.0 to 13.0.0 by @dependabot[bot] in #23541
- Bump virtualenv from 21.7.13 to 21.14.9 by @dependabot[bot] in #23540
- Bump virtualenv from 21.14.9 to 21.14.13 by @dependabot[bot] in #23584
- Bump storybook from 10.6.0 to 10.6.3 in /ui-v2 by @dependabot[bot] in #23549
- Bump lodash-es and mermaid in /ui-v2 by @dependabot[bot] in #23551
- Bump dompurify from 3.4.16 to 3.4.17 in /ui-v2 by @dependabot[bot] in #23548
- Bump undici from 8.11.2 to 8.12.3 in /ui-v2 by @dependabot[bot] in #23581
- Bump fast-uri from 3.1.7 to 3.1.9 in /ui-v2 by @dependabot[bot] in #23582
- Bump msgpack from 1.2.1 to 1.2.3 by @dependabot[bot] in #23633
- Bump qs from 6.16.0 to 6.17.0 in /ui by @dependabot[bot] in #23632
- Fix flaky
TestRemoteFileSystemtree-project tests by @devin-ai-integration[bot] in #23554 - Fix flaky worker channel tests racing a 1s wall-clock deadline by @devin-ai-integration[bot] in #23450
- Fix flaky
TestWorkerLoggingtest caused by logging leak fromprefect configCLI tests by @devin-ai-integration[bot] in #23297 - Fix flaky
StateFilterdiscovery cap search test by @devin-ai-integration[bot] in #23556 - Fix flaky
date_diff_secondsfrom-now tests by @devin-ai-integration[bot] in #23451 - Fix background worker shutdown hang when worker cancellation is lost by @devin-ai-integration[bot] in #23511
- Ignore Python 3.15 multi-threaded fork warning in forked child service test by @devin-ai-integration[bot] in #23562
- Fix flaky events E2E tests by filtering by exact resource IDs by @devin-ai-integration[bot] in #23579
- Fix flaky
TestProcessPoolTaskRunner::test_submit_remains_non_blockingby @devin-ai-integration[bot] in #23605 - Fix flaky
TestFlowRunLogstests by filtering logs by flow run by @devin-ai-integration[bot] in #23611 - Refresh and verify Docker image CA trust stores by @zzstoatzz in #23517
- Document SQLite
BEGIN IMMEDIATEcontract in server AGENTS.md by @devin-ai-integration[bot] in #23560 - Document
_pendulum_callcontract insrc/prefectAGENTS.md by @devin-ai-integration[bot] in #23499
- Document Python 3.15 support and ISO duration inputs for
withinby @devin-ai-integration[bot] in #23498 - Document flow retries for returned Failed states by @devin-ai-integration[bot] in #23543
- Document microbatch task runs and partial success in
PrefectDbtRunnerby @devin-ai-integration[bot] in #23361 - Correct the reverse-proxy UI settings table by @himanshuchawla0807-gif in #23479
- Document
event.urlin automation templates by @devin-ai-integration[bot] in #23607 - Set canonical URLs to www.prefect.io by @maximearmstrong in #23641
- Link to the docs at www.prefect.io/docs by @maximearmstrong in #23642
- Fix broken docs links and stop redirecting missing pages to the homepage by @maximearmstrong in #23651
3.9.0 - Pendulum’s last swing
Released on October 21, 2026 Breaking Changes ⚠️- Drop Python 3.10 support by @devin-ai-integration[bot] in #23324
- Remove deprecated Runner execution paths by @desertaxle in #23496
- Deprecate Pendulum datetime behavior on Python 3.11–3.12 by @devin-ai-integration[bot] in #23328
- Add Python 3.15 support by @devin-ai-integration[bot] in #23400
- Add opt-in clearing for empty deployment schedules by @mifuha in #23412
- Cut CPU spent delivering events and API logs by @desertaxle in #23473
- Open a run’s artifacts directly from the Artifacts tab and run graph in ui-v2 by @JonasFockstedt in #23339
- Read automations with action types this version doesn’t know by @nathandpeterson in #23426
- Recover cancellation and suspension observers from websocket outages by @devin-ai-integration[bot] in #23421
- Keep the runner healthcheck healthy while the API is in maintenance by @jimid27 in #23325
- Skip duplicate worker submissions of runs that already hold a limit slot by @devin-ai-integration[bot] in #23341
- Fix prefect.yaml creation when optional contents is omitted by @MuhammadWaleed12 in #23334
- Check out pinned
commit_shawhen a git checkout already exists by @devin-ai-integration[bot] in #23374 - Preserve pytz timezone names in
RRuleSchedule.from_rrule()by @devin-ai-integration[bot] in #23396 - Fix
visit_collectionreturning another object’s cached result after id reuse by @novain-shibu in #23404 - Make
*args/**kwargsoptional collections in flow parameter schemas by @devin-ai-integration[bot] in #23418 - Return run input from async
pause_flow_runwhen pause is rejected by @devin-ai-integration[bot] in #23435 - Allow
Task.with_options(tags=[])to clear existing tags by @devin-ai-integration[bot] in #23444 - Delete every deployment with
prefect deployment delete --allby @devin-ai-integration[bot] in #23440 - Unwrap
FieldInfodefaults for unmapped parameters intask.map()by @devin-ai-integration[bot] in #23369 - Count expect events that race or precede a proactive trigger’s window by @chrisguidry in #23445
- Respect
--hoursinwork-pool previewandwork-queue preview --poolby @LuisFigueroaG in #23300 - Raise
ValueErrorfor negative timeout inpause_flow_runby @kingsley-123 in #22761 - Fix
prefect deploydropping list items templated from step outputs by @MohammadHijjawi97 in #23381 - Copy hook lists in
with_optionsfor tasks and flows by @spicysharkco in #23442 - Return empty list from
extract_instanceswhen there is no match by @udsy19 in #23427 - Fix
timeout=0raising aTimeoutErrorinPrefectFutureList.resultby @uinstinct in #23408 - Fix silently skipped task retries in
retry_condition_fnby @uinstinct in #23397 - Fix overlapping action branches in the automation JSON schema by @devin-ai-integration[bot] in #23448
- Use
min_lengthandmax_lengthon request bodies so the server imports on FastAPI 0.155 by @bunchesofdonald in #23476 - Make flow run activity cells navigable by @VivekVRobo in #23352
- Render run graph artifact icons instead of black boxes in ui-v2 by @JonasFockstedt in #23348
- Bump
source-map-jsfrom 1.2.1 to 1.2.2 in /ui by @dependabot[bot] in #23315 - Bump
postcss-selector-parserfrom 6.1.2 to 6.1.4 in /ui by @dependabot[bot] in #23288 - Bump
serovalfrom 1.6.2 to 1.6.8 in /ui-v2 by @dependabot[bot] in #23314 - Bump
snowflake-connector-pythonfrom 4.7.1 to 4.7.3 by @dependabot[bot] in #23316 - Bump
werkzeugfrom 3.1.6 to 3.1.9 by @dependabot[bot] in #23317 - Bump
makofrom 1.3.12 to 1.4.2 by @dependabot[bot] in #23318 - Bump
multidictfrom 6.7.0 to 6.9.1 by @dependabot[bot] in #23319 - Bump
uvfrom 0.12.10 to 0.12.18 in /scripts/proxy-test by @dependabot[bot] in #23365 - Bump
cairosvgfrom 2.9.0 to 2.9.1 by @dependabot[bot] in #23363 - Bump
source-map-jsfrom 1.2.1 to 1.2.2 in /ui-v2 by @dependabot[bot] in #23364 - Bump
dompurifyfrom 3.4.12 to 3.4.16 in /ui-v2 by @dependabot[bot] in #23362 - Bump
aiohttpfrom 3.14.3 to 3.14.4 by @dependabot[bot] in #23462 - Bump
follow-redirectsfrom 1.16.0 to 1.16.1 in /ui by @dependabot[bot] in #23480 - Bump
vitefrom 8.2.2 to 8.3.4 in /ui by @dependabot[bot] in #23485 - Cap
fastapibelow 0.151 by @bunchesofdonald in #23478 - Update
certifianduvfor the eMudhra CA compromise by @desertaxle in #23483
- Keep the patched test clock timezone-aware on Python 3.12 by @chrisguidry in #23465
- Wait for the events client to confirm events before asserting in checkpoint tests by @bunchesofdonald in #23477
- Guard internal call sites against Pendulum deprecation warnings by @devin-ai-integration[bot] in #23497
- Replace dead Sanity logo URLs in bundled collection metadata by @mattiamatrix in #23409
- Fix broken in-page anchors in the events reference by @wznhf78gyf-bot in #23331
- Fix
itemstype in the base job template customization docs by @rjafarau in #23388 - Document
UnknownActionfor automations and transfer skips by @devin-ai-integration[bot] in #23446 - Document held expect events for proactive triggers with
afterby @devin-ai-integration[bot] in #23467