PrefectHQ/fastmcp · error · TypeError
Version must be a string, int, or float, got bool: {v!r}
Error message
Version must be a string, int, or float, got bool: {v!r} What it means
FastMCP component versions must be scalar (str, int, or float). Booleans are explicitly rejected even though bool is a subclass of int in Python, because version=True is surely unintended and would otherwise coerce to "True". A TypeError is raised naming the offending value.
Source
Thrown at fastmcp_slim/fastmcp/utilities/components.py:57
def _convert_set_default_none(maybe_set: set[T] | Sequence[T] | None) -> set[T]:
"""Convert a sequence to a set, defaulting to an empty set if None."""
if maybe_set is None:
return set()
if isinstance(maybe_set, set):
return maybe_set
return set(maybe_set)
def _coerce_version(v: str | int | float | None) -> str | None:
"""Coerce version to string, accepting int, float, or str.
Raises TypeError for non-scalar types (list, dict, set, etc.).
Raises ValueError if version contains '@' (used as key delimiter).
"""
if v is None:
return None
if isinstance(v, bool):
raise TypeError(f"Version must be a string, int, or float, got bool: {v!r}")
if not isinstance(v, (str, int, float)):
raise TypeError(
f"Version must be a string, int, or float, got {type(v).__name__}: {v!r}"
)
version = str(v)
if "@" in version:
raise ValueError(
f"Version string cannot contain '@' (used as key delimiter): {version!r}"
)
return version
class FastMCPComponent(FastMCPBaseModel):
"""Base class for FastMCP tools, prompts, resources, and resource templates."""
KEY_PREFIX: ClassVar[str] = ""
def __init_subclass__(cls, **kwargs: Any) -> None:View on GitHub (pinned to 1f02114297)
Solutions
- Pass a real string/int/float version, e.g. version="1.0.0"
- Fix the config so the version field is quoted as a string
- Validate/coerce the version value before constructing the component
Example fix
// before Tool(fn, name="t", version=True) // after Tool(fn, name="t", version="1.0.0")
Defensive patterns
Strategy: type-guard
Validate before calling
def valid_version(v) -> bool:
return v is None or (isinstance(v, (str, int, float)) and not isinstance(v, bool)) Type guard
def is_scalar_version(v: object) -> bool:
return isinstance(v, (str, int, float)) and not isinstance(v, bool) Try / catch
try:
tool = Tool(fn, version=v)
except TypeError as e:
if "got bool" in str(e):
tool = Tool(fn, version=str(int(v)))
else:
raise Prevention
- Quote version strings in YAML/JSON configs
- Never pass boolean flags in the version parameter position
- Validate config values before constructing components
When it happens
Trigger: Passing version=True/False to a component constructor (tool, resource, prompt, etc.) or to from_tool/versioned registration, often from unvalidated config or dynamic values.
Common situations: YAML/JSON config where a version is written as `true`; a flag variable accidentally passed as the version argument; dynamic version variables that can hold booleans.
Related errors
- Version must be a string, int, or float, got {type(v).__name
- Cannot specify both a name as first argument and as keyword
- First argument to @{decorator_name} must be a function, stri
- A completion handler returned a str; return a list of string
- Got unexpected keyword argument(s): {', '.join(sorted(unknow
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/91c03e2226b7a4e1.
Report an issue: GitHub.