aio-libs/aiohttp · error · ValueError

timeout parameter cannot be of {type} type, please use 'time

Error message

timeout parameter cannot be of {type} type, please use 'timeout=ClientTimeout(...)'

What it means

Raised in ClientSession.__init__ (client.py:350) when the `timeout` argument is not a ClientTimeout instance. aiohttp 3.x replaced scalar timeout values with the ClientTimeout dataclass; passing an int/float (the old requests-style API) or any unrelated type now fails fast instead of being silently misinterpreted. The check runs after `sentinel`/`None` resolution, so only genuinely wrong types reach it.

Source

Thrown at aiohttp/client.py:350

        else:
            self._base_url = URL(base_url)
            self._base_url_origin = self._base_url.origin()
            assert self._base_url.absolute, "Only absolute URLs are supported"
        if self._base_url is not None and not self._base_url.path.endswith("/"):
            raise ValueError("base_url must have a trailing '/'")

        if not isinstance(ssl, SSL_ALLOWED_TYPES):
            raise TypeError(
                "ssl should be SSLContext, Fingerprint, or bool, "
                f"got {ssl!r} instead."
            )

        loop = asyncio.get_running_loop()

        if timeout is sentinel or timeout is None:
            timeout = ClientTimeout()
        if not isinstance(timeout, ClientTimeout):
            raise ValueError(
                f"timeout parameter cannot be of {type(timeout)} type, "
                "please use 'timeout=ClientTimeout(...)'",
            )
        self._timeout = timeout

        if ssl_shutdown_timeout is not sentinel:
            warnings.warn(
                "The ssl_shutdown_timeout parameter is deprecated and will be removed in aiohttp 4.0",
                DeprecationWarning,
                stacklevel=2,
            )

        if connector is None:
            connector = TCPConnector(ssl_shutdown_timeout=ssl_shutdown_timeout)
        # Initialize these three attrs before raising any exception,
        # they are used in __del__
        self._connector = connector
        self._loop = loop

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Wrap the value in ClientTimeout: `from aiohttp import ClientTimeout; ClientSession(timeout=ClientTimeout(total=30))`.
  2. For per-request overrides pass `timeout=ClientTimeout(total=N)` to `session.request(...)` / `session.get(...)`.
  3. If forwarding a possibly-numeric config value, normalize it: `timeout = ClientTimeout(total=t) if isinstance(t, (int, float)) else t`.

Example fix

// before
session = aiohttp.ClientSession(timeout=30)
// after
from aiohttp import ClientTimeout
session = aiohttp.ClientSession(timeout=ClientTimeout(total=30))
Defensive patterns

Strategy: validation

Validate before calling

from aiohttp import ClientTimeout

def make_timeout(t):
    if t is None or t is sentinel:
        return ClientTimeout()
    if isinstance(t, ClientTimeout):
        return t
    if isinstance(t, (int, float)):
        return ClientTimeout(total=t)
    raise TypeError(f'unsupported timeout type: {type(t)!r}')

Type guard

from aiohttp import ClientTimeout

def is_valid_timeout(t) -> bool:
    return t is None or isinstance(t, ClientTimeout)

Try / catch

try:
    session = aiohttp.ClientSession(timeout=cfg_timeout)
except ValueError as e:
    if 'timeout parameter cannot be' in str(e):
        session = aiohttp.ClientSession(timeout=ClientTimeout(total=30))
    else:
        raise

Prevention

When it happens

Trigger: Calling `ClientSession(timeout=10)`, `ClientSession(timeout=30.0)`, or `session.get(url, timeout=5)`. Anywhere a numeric, tuple, or custom object is passed where aiohttp expects `ClientTimeout(...)`.

Common situations: Porting code from `requests` (which accepts numeric timeouts), copy-pasting answers that predate aiohttp 3.0, or using a shared helper that forwards a `timeout` kwarg verbatim from a config file.

Related errors


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/b1a9f8d7d2865611.json. Report an issue: GitHub.