PrefectHQ/fastmcp · error · ValueError
Invalid boolean value for {param_name}: {param_value!r}
Error message
Invalid boolean value for {param_name}: {param_value!r} What it means
FunctionResourceTemplate converts URI-template path parameters into typed Python values based on annotations. When a {param} is annotated as bool and the URI segment string is not a recognized boolean literal (true/1/yes or false/0/no, case-insensitive), the conversion raises this ValueError.
Source
Thrown at fastmcp_slim/fastmcp/resources/template.py:414
param = sig.parameters[param_name]
annotation = param.annotation
if annotation is inspect.Parameter.empty or annotation is str:
continue
try:
if annotation is int:
kwargs[param_name] = int(param_value)
elif annotation is float:
kwargs[param_name] = float(param_value)
elif annotation is bool:
lower = param_value.lower()
if lower in ("true", "1", "yes"):
kwargs[param_name] = True
elif lower in ("false", "0", "no"):
kwargs[param_name] = False
else:
raise ValueError(
f"Invalid boolean value for {param_name}: {param_value!r}"
)
except (ValueError, AttributeError):
raise
# self.fn is wrapped by without_injected_parameters which handles
# dependency resolution internally, so we call it directly
result = self.fn(**kwargs)
if inspect.isawaitable(result):
result = await result
return result
@classmethod
def from_function(
cls,
fn: Callable[..., Any],
uri_template: str,View on GitHub (pinned to 1f02114297)
Solutions
- Use one of true/1/yes or false/0/no (any case) in the URI segment
- Change the template parameter annotation to str and convert manually in the function with explicit accepted values
- Validate/normalize the URI before requesting the resource
Example fix
// before
GET data://flag/on # {enabled: bool}
// after
GET data://flag/yes # accepted: true/1/yes, false/0/no
// or change annotation:
@mcp.resource("data://flag/{enabled}")
def get(enabled: str): ... Defensive patterns
Strategy: validation
Validate before calling
BOOL_WORDS = {"true", "1", "yes", "false", "0", "no"}
def valid_bool_param(value: str) -> bool:
return value.lower() in BOOL_WORDS Type guard
def as_bool(value: str) -> bool | None:
if value.lower() in ("true", "1", "yes"):
return True
if value.lower() in ("false", "0", "no"):
return False
return None Try / catch
try:
content = await template.read({"enabled": segment})
except ValueError as e:
if str(e).startswith("Invalid boolean value"):
segment = "true" if segment not in ("false", "0", "no") else "false" Prevention
- Only use annotated bool template params when clients control the URI format
- Annotate ambiguous params as str and convert with explicit accepted values
- Document accepted boolean literals (true/1/yes, false/0/no) for URI consumers
When it happens
Trigger: Template 'data://flag/{enabled}' with enabled: bool and a request to data://flag/maybe; URIs with unexpected segment values like 'on', 'off', 'yes!' or empty-ish strings not in the accepted lists.
Common situations: Client-generated URIs with free-form boolean-ish words; localized or shorthand values (Y/N, oui/non) not covered by the accepted literals.
Related errors
- Either name or uri must be provided
- Subclasses must implement read() or override create_resource
- Subclasses must implement create_resource(). Use FunctionRes
- No resource data available
- module {__name__!r} has no attribute {name!r}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/a0b78e37b419cf8f.
Report an issue: GitHub.