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 = loopView on GitHub (pinned to c0ef574e29)
Solutions
- Wrap the value in ClientTimeout: `from aiohttp import ClientTimeout; ClientSession(timeout=ClientTimeout(total=30))`.
- For per-request overrides pass `timeout=ClientTimeout(total=N)` to `session.request(...)` / `session.get(...)`.
- 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
- Always import and use ClientTimeout; never pass raw numbers.
- Centralize ClientTimeout construction in a config helper so callers can't pass wrong types.
- Run mypy with the aiohttp stubs — the typed `timeout: ClientTimeout` parameter catches numeric misuse at type-check time.
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
- Connection timeout to host {url}
- base_url must have a trailing '/'
- ssl should be SSLContext, Fingerprint, or bool, got {ssl!r}
- Session and connector have to use same event loop
- Inheritance class {cls} from ClientSession is forbidden
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/b1a9f8d7d2865611.json.
Report an issue: GitHub.