From c841c429293a606e805b0a26959c13732c398392 Mon Sep 17 00:00:00 2001 From: Chaitanya Sai Meka Date: Mon, 10 Nov 2025 10:32:46 +0530 Subject: [PATCH] docs: clarify misleading 'Required, can be None' section in query param validation --- .../tutorial/query-params-str-validations.md | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/en/docs/tutorial/query-params-str-validations.md b/docs/en/docs/tutorial/query-params-str-validations.md index adf08a924..332636080 100644 --- a/docs/en/docs/tutorial/query-params-str-validations.md +++ b/docs/en/docs/tutorial/query-params-str-validations.md @@ -260,11 +260,34 @@ So, when you need to declare a value as required while using `Query`, you can si ### Required, can be `None` { #required-can-be-none } -You can declare that a parameter can accept `None`, but that it's still required. This would force clients to send a value, even if the value is `None`. +You might want to declare that a parameter can accept `None`, but is still required. -To do that, you can declare that `None` is a valid type but simply do not declare a default value: +However, because of how **HTTP query parameters** work, clients cannot actually send a real `None` (or `null`) value — query parameters are always sent as **strings**. +That means you cannot truly have a *required* parameter that also allows a real `None` value. -{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *} +For example, you might try: + +```Python +q: Annotated[str | None, Query(min_length=3)] = ... +``` + +But this will still expect a string value, and if the client omits q or tries to send q=None, FastAPI will raise a validation error. +In other words, None is not an acceptable runtime value for query parameters — only strings are. + +If you want to accept special values (like "None" or an empty string) and interpret them as None in your application, you can handle them manually in your function: + +```Python +from fastapi import FastAPI, Query +from typing import Annotated + +app = FastAPI() + +@app.get("/items/") +async def read_items(q: Annotated[str | None, Query()] = ...): + if q in ("None", "", "null"): + q = None + return {"q": q} +``` ## Query parameter list / multiple values { #query-parameter-list-multiple-values }