SeleniumHQ/selenium · error · TypeError
Timeouts can only be an int or a float
Error message
Timeouts can only be an int or a float
What it means
Raised by Timeouts._convert() when a value assigned to implicit_wait, page_load, or script is neither an int nor a float. _convert multiplies by 1000 to store milliseconds internally, so non-numeric types (strings, None, bool-as-string) are rejected with a TypeError. The check runs both in the constructor and in the descriptor __set__ on every assignment.
Source
Thrown at py/selenium/webdriver/common/timeouts.py:91
Note: This does not set the value on the remote end.
"""
page_load = _TimeoutsDescriptor("_page_load")
"""Number of seconds to wait for the page to load.
Note: This does not set the value on the remote end.
"""
script = _TimeoutsDescriptor("_script")
"""Number of seconds to wait for an asynchronous script to finish execution.
Note: This does not set the value on the remote end.
"""
def _convert(self, timeout: float) -> int:
if isinstance(timeout, (int, float)):
return int(float(timeout) * 1000)
raise TypeError("Timeouts can only be an int or a float")
def _to_json(self) -> JSONTimeouts:
timeouts: JSONTimeouts = {}
if self._implicit_wait:
timeouts["implicit"] = self._implicit_wait
if self._page_load:
timeouts["pageLoad"] = self._page_load
if self._script:
timeouts["script"] = self._script
return timeouts
View on GitHub (pinned to aa36b38e69)
Solutions
- Convert config strings to float before passing: Timeouts(implicit_wait=float(value)).
- Use numeric literals in code: Timeouts(implicit_wait=10).
- Validate/normalize config at load time so timeout values are always numeric.
- Guard None values with a sensible numeric default before assignment.
Example fix
# before
wait = os.getenv('IMPLICIT_WAIT') # returns '10' (str)
timeouts = Timeouts(implicit_wait=wait) # -> TypeError
# after
wait = float(os.getenv('IMPLICIT_WAIT', 0))
timeouts = Timeouts(implicit_wait=wait) Defensive patterns
Strategy: type-guard
Validate before calling
def coerce_timeout(v):
if v is None:
return 0
f = float(v)
return f
timeouts = Timeouts(implicit_wait=coerce_timeout(cfg.get('implicit_wait'))) Type guard
def is_numeric_timeout(v) -> bool:
return isinstance(v, (int, float)) and not isinstance(v, bool) Try / catch
from selenium.webdriver.common.timeouts import Timeouts
try:
t = Timeouts(implicit_wait=raw)
except TypeError as e:
if 'Timeouts can only be an int or a float' in str(e):
t = Timeouts(implicit_wait=float(raw)) Prevention
- Normalize config-sourced values to float at load time.
- Treat None as 0 rather than passing it through.
- Add unit tests asserting timeout setters accept int and float only.
When it happens
Trigger: Constructing Timeouts(implicit_wait='10'), assigning driver.timeouts.implicit_wait = '5', or passing a string/None from config parsing (e.g. os.getenv returning a string, or a JSON value that was a string instead of a number).
Common situations: Reading timeout values from environment variables or config files that yield strings, deserializing JSON where numbers were quoted, passing a timedelta object, or a None default leaking through.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- not a string or number
- service_args must be a sequence
- Level must be >= 0
- Port needs to be an integer
- Argument to isShown must be of type Element
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/d6b3cd3b6b98bbdc.
Report an issue: GitHub.