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

  1. Use one of true/1/yes or false/0/no (any case) in the URI segment
  2. Change the template parameter annotation to str and convert manually in the function with explicit accepted values
  3. 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

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


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/a0b78e37b419cf8f. Report an issue: GitHub.