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

  1. Convert config strings to float before passing: Timeouts(implicit_wait=float(value)).
  2. Use numeric literals in code: Timeouts(implicit_wait=10).
  3. Validate/normalize config at load time so timeout values are always numeric.
  4. 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

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

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/d6b3cd3b6b98bbdc. Report an issue: GitHub.