PrefectHQ/fastmcp · error · ValueError

max_size must be positive, got {max_size}

Error message

max_size must be positive, got {max_size}

What it means

A ValueError from ResponseLimitingMiddleware.__init__ when max_size is zero or negative. The middleware truncates responses larger than max_size bytes, so a non-positive cap is invalid and construction fails fast with the offending value included in the message.

Source

Thrown at fastmcp_slim/fastmcp/server/middleware/response_limiting.py:67

    """

    def __init__(
        self,
        *,
        max_size: int = 1_000_000,
        truncation_suffix: str = "\n\n[Response truncated due to size limit]",
        tools: list[str] | None = None,
    ) -> None:
        """Initialize response limiting middleware.

        Args:
            max_size: Maximum response size in bytes. Defaults to 1MB (1,000,000).
            truncation_suffix: Suffix to append when truncating responses.
                Defaults to "\\n\\n[Response truncated due to size limit]".
            tools: List of tool names to apply limiting to. If None, applies to all.
        """
        if max_size <= 0:
            raise ValueError(f"max_size must be positive, got {max_size}")
        self.max_size = max_size
        self.truncation_suffix = truncation_suffix
        self.tools = set(tools) if tools is not None else None

    def _limits_tool(self, name: str) -> bool:
        return self.tools is None or name in self.tools

    def _truncate_to_result(
        self,
        text: str,
        meta: dict[str, Any] | None = None,
    ) -> ToolResult:
        """Truncate text to fit within max_size and wrap in ToolResult."""
        suffix_bytes = len(self.truncation_suffix.encode("utf-8"))
        # Account for JSON wrapper overhead: {"content":[{"type":"text","text":"..."}]}
        overhead = 50
        target_size = self.max_size - suffix_bytes - overhead

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass a positive max_size in bytes (default 1,000,000).
  2. If you intended 'no limit', do not register the middleware instead of passing 0.
  3. Validate config-derived sizes before constructing the middleware.

Example fix

// before
size = int(os.getenv("MAX_RESPONSE_SIZE", "0"))
mw = ResponseLimitingMiddleware(max_size=size)  # ValueError

// after
size = int(os.getenv("MAX_RESPONSE_SIZE", "1000000"))
mw = ResponseLimitingMiddleware(max_size=max(size, 1))
Defensive patterns

Strategy: validation

Validate before calling

max_size = int(os.getenv("MAX_RESPONSE_SIZE", "1000000"))
if max_size <= 0:
    raise ValueError(f"MAX_RESPONSE_SIZE must be positive bytes, got {max_size}")
mw = ResponseLimitingMiddleware(max_size=max_size)

Try / catch

try:
    mw = ResponseLimitingMiddleware(max_size=max_size)
except ValueError as e:
    logging.warning("bad max_size, using default: %s", e)
    mw = ResponseLimitingMiddleware()  # 1MB default

Prevention

When it happens

Trigger: ResponseLimitingMiddleware(max_size=0) or a negative value, typically from an unset/zero config value or a unit confusion (e.g. passing size in KB while the code expects bytes, yielding 0).

Common situations: MAX_RESPONSE_SIZE env var defaulting to 0; integer division like kb_to_bytes(0); mixing up max_size semantics with a 'limit disabled' sentinel of 0.

Related errors


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