<@ULVA73B9P> **Upgrading the Prefect server to 3....
# ask-marvin
c
@Marvin Upgrading the Prefect server to 3.6.19+ breaks clients on 3.5.0 with a 422 on
POST /task_runs/
PR #20822 upgraded FastAPI from 0.128 to 0.132 and changed the client's
create_task_run
to send
json=
instead of
content=
. But no server-side backward compatibility was added. Since the server's FastAPI pin is
>=0.111.0,<1.0.0
, any server upgrade can pull in FastAPI 0.132+, which rejects the old client's
content=
(raw JSON string) body with: Input should be a valid dictionary or object to extract fields from This means you can't upgrade the server independently of the client — a server upgrade silently breaks all deployed clients still on
<3.6.19
. Is that right?
m
Error: unhandled errors in a TaskGroup (1 sub-exception)
Sorry, I encountered an error while processing your request. Please try again.
c
@Marvin try again
m
thought for 12.3 seconds
I’m not sure what you’d like me to try again—could you share a bit more detail? - What are you trying to do with Prefect? - Which version are you on (2.x or 3.x)? - Where is it running (local, Docker, Kubernetes) and what worker/pool type? - Any error message or traceback? - A minimal code snippet or the CLI command you ran would help a ton. Paste whatever you have and I’ll jump right back in with a corrected answer or example.
c
@Marvin Upgrading the Prefect server to 3.6.19+ breaks clients on 3.5.0 with a 422 on POST /task_runs/ PR #20822 upgraded FastAPI from 0.128 to 0.132 and changed the client's create_task_run to send json= instead of content=. But no server-side backward compatibility was added. Since the server's FastAPI pin is >=0.111.0,<1.0.0, any server upgrade can pull in FastAPI 0.132+, which rejects the old client's content= (raw JSON string) body with: Input should be a valid dictionary or object to extract fields from This means you can't upgrade the server independently of the client — a server upgrade silently breaks all deployed clients still on <3.6.19. Is that right?
m
thought for 181.3 seconds
Short answer: yes. Upgrading only the server to 3.6.19+ can break 3.5.0 clients when they POST /task_runs. The root cause is FastAPI 0.132’s stricter JSON body handling plus older clients sending the body with
content=
(raw JSON string) instead of
json=
. FastAPI 0.132 won’t parse that as JSON, so the server receives a string where it expects a dict and returns 422 (“Input should be a valid dictionary or object…”). - Change was introduced in PR #20822 (client switched to
json=
); there isn’t a server-side compatibility shim. - Release notes: Prefect 3.6.19 Recommended paths: - Preferred: upgrade clients/agents/workers to >= 3.6.19 at the same time as the server.
Copy code
pip install --upgrade "prefect>=3.6.19"
  prefect version
- Temporary mitigation if you must stagger: keep the server on < 3.6.19 or pin FastAPI < 0.132 in your server image/env until all clients are upgraded.
Copy code
# option A: pin Prefect server
  prefect<3.6.19

  # option B: if you must run 3.6.19 server, constrain FastAPI
  fastapi<0.132
- If you control custom client code on 3.5.0, switch your direct calls to use
json=...
(but Prefect’s built-in client change is only in 3.6.19+, so upgrading the library is the clean fix). Are you on Prefect OSS or Cloud, and do you need guidance for a staggered rollout (e.g., Helm/Docker pinning)? I can suggest concrete steps for your deployment setup.