PrefectHQ/fastmcp · error · ValueError

interval_ms must be positive

Error message

interval_ms must be positive

What it means

A ValueError raised in the PingMiddleware constructor when interval_ms is zero or negative. The middleware pings active sessions on a timer, so a non-positive interval would spin or be meaningless; construction is rejected immediately.

Source

Thrown at fastmcp_slim/fastmcp/server/middleware/ping.py:39

        from fastmcp import FastMCP
        from fastmcp.server.middleware import PingMiddleware

        mcp = FastMCP("MyServer")
        mcp.add_middleware(PingMiddleware(interval_ms=5000))
        ```
    """

    def __init__(self, interval_ms: int = 30000):
        """Initialize ping middleware.

        Args:
            interval_ms: Interval between pings in milliseconds (default: 30000)

        Raises:
            ValueError: If interval_ms is not positive
        """
        if interval_ms <= 0:
            raise ValueError("interval_ms must be positive")
        self.interval_ms = interval_ms
        self._active_sessions: set[int] = set()
        self._lock = anyio.Lock()

    async def on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any:
        """Start ping task on first message from a connection."""
        if (
            context.fastmcp_context is None
            or context.fastmcp_context.request_context is None
        ):
            return await call_next(context)

        session = context.fastmcp_context.session
        # SDK v2 constructs a ServerSession per request; the stable per-connection
        # identity lives on the underlying Connection. Key the keepalive loop off
        # it so one ping task runs for the whole connection and is torn down when
        # the connection closes.
        connection = getattr(session, "_connection", None)

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass a positive interval_ms (default is 30000).
  2. If the value comes from config/env, validate or clamp it before constructing the middleware.

Example fix

// before
interval = int(os.getenv("PING_INTERVAL_MS", "0"))
mw = PingMiddleware(interval_ms=interval)  # ValueError

// after
interval = max(int(os.getenv("PING_INTERVAL_MS", "30000")), 1)
mw = PingMiddleware(interval_ms=interval)
Defensive patterns

Strategy: validation

Validate before calling

interval_ms = int(os.getenv("PING_INTERVAL_MS", "30000"))
assert interval_ms > 0, f"PING_INTERVAL_MS must be positive, got {interval_ms}"
mw = PingMiddleware(interval_ms=interval_ms)

Try / catch

try:
    mw = PingMiddleware(interval_ms=interval_ms)
except ValueError as e:
    logging.warning("bad ping interval, using default: %s", e)
    mw = PingMiddleware()

Prevention

When it happens

Trigger: Instantiating PingMiddleware(interval_ms=0) or PingMiddleware(interval_ms=-100), e.g. from a computed or misconfigured config value (0 from an unset env var parsed as int).

Common situations: Environment variable or YAML config supplying 0 for the interval; arithmetic like ms = seconds * 1000 where seconds defaulted to 0; copying a sample config with a placeholder 0.

Related errors


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