PrefectHQ/fastmcp · error · ValueError
Query parameters {invalid_query_params} must be optional fun
Error message
Query parameters {invalid_query_params} must be optional function parameters with default values What it means
RFC 6570 query parameters (?name={value}) are optional by nature - a client may omit them. To support omission, FastMCP requires every function parameter bound to a query parameter to have a default value. Required (no-default) parameters bound to the query section raise this error.
Source
Thrown at fastmcp_slim/fastmcp/resources/template.py:516
required_params = {
p
for p in func_params
if user_sig.parameters[p].default is inspect.Parameter.empty
and user_sig.parameters[p].kind != inspect.Parameter.VAR_KEYWORD
}
optional_params = {
p
for p in func_params
if user_sig.parameters[p].default is not inspect.Parameter.empty
and user_sig.parameters[p].kind != inspect.Parameter.VAR_KEYWORD
}
# Validate RFC 6570 query parameters
# Query params must be optional (have defaults)
if query_params:
invalid_query_params = query_params - optional_params
if invalid_query_params:
raise ValueError(
f"Query parameters {invalid_query_params} must be optional function parameters with default values"
)
# Check if required parameters are a subset of the path parameters
if not required_params.issubset(path_params):
raise ValueError(
f"Required function arguments {required_params} must be a subset of the URI path parameters {path_params}"
)
# Check if all URI parameters are valid function parameters (skip if **kwargs present)
if not any(
param.kind == inspect.Parameter.VAR_KEYWORD
for param in sig.parameters.values()
):
if not all_uri_params.issubset(func_params):
raise ValueError(
f"URI parameters {all_uri_params} must be a subset of the function arguments: {func_params}"
)View on GitHub (pinned to 1f02114297)
Solutions
- Give the query-bound function parameter a default value (e.g. limit: int = 10)
- Move the parameter into the URI path section if it must be required
- Remove the parameter from both the URI and the function if it isn't needed
Example fix
// before
def list_items(key: str, limit: int): ...
template(uri_template="items://{key}?limit={limit}")
// after
def list_items(key: str, limit: int = 10): ...
template(uri_template="items://{key}?limit={limit}") Defensive patterns
Strategy: validation
Validate before calling
import inspect, re
def check_query_params(fn, uri_template):
query = uri_template.split("?", 1)[-1]
qparams = {p.replace("-", "_") for p in re.findall(r"\{(\w[-\w]*)\}", query)}
sig = inspect.signature(fn)
for name in qparams:
p = sig.parameters.get(name)
if p is None or p.default is inspect.Parameter.empty:
raise TypeError(f"query param {name} needs a default value") Type guard
def query_params_optional(fn, uri_template) -> bool:
import inspect, re
query = uri_template.split("?", 1)[-1]
qp = {p.replace("-", "_") for p in re.findall(r"\{(\w[-\w]*)\}", query)}
params = inspect.signature(fn).parameters
return all(n in params and params[n].default is not inspect.Parameter.empty for n in qp) Try / catch
try:
tpl = FunctionResourceTemplate.from_function(fn, uri_template=uri)
except ValueError as e:
if "must be optional" in str(e):
fn = add_defaults(fn) # bind defaults for query-bound params
tpl = FunctionResourceTemplate.from_function(fn, uri_template=uri)
else:
raise Prevention
- Give every query-bound parameter a sensible default
- Keep required data in the path, optional data in the query
- Review function signatures whenever moving params between path and query
When it happens
Trigger: Registering a template where a parameter appearing only in the URI query part (e.g. ?limit={limit}) maps to a function parameter without a default, like def fn(key: str, limit: int).
Common situations: Adding an optional query filter but declaring the function param as required; moving a parameter from the path to the query section without adding a default; stricter signatures after refactoring.
Related errors
- URI template parameters '{seen[normalized]}' and '{raw_name}
- URI template must contain at least one parameter
- Required function arguments {required_params} must be a subs
- URI parameters {all_uri_params} must be a subset of the func
- Expected integer, got {raw!r}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/f02080640102d3f9.
Report an issue: GitHub.