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

  1. Pass a real string/int/float version, e.g. version="1.0.0"
  2. Fix the config so the version field is quoted as a string
  3. 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

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


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