SeleniumHQ/selenium · error · ValueError
Timeout keys can only be one of the following: implicit, pag
Error message
Timeout keys can only be one of the following: implicit, pageLoad, script
What it means
The timeouts property expects a dict whose keys are a subset of the W3C timeout names: 'implicit', 'pageLoad', 'script'. If any key is outside this set, ValueError is raised. Note it iterates value.keys(), so a non-dict (e.g. a string or None) will raise AttributeError on .keys() before reaching the validation.
Source
Thrown at py/selenium/webdriver/common/options.py:141
Args:
timeouts: values in milliseconds for implicit wait, page load and script timeout
Returns:
Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)
"""
def __init__(self, name):
self.name = name
def __get__(self, obj, cls):
return obj._caps.get(self.name)
def __set__(self, obj, value):
if all(x in ("implicit", "pageLoad", "script") for x in value.keys()):
obj.set_capability(self.name, value)
else:
raise ValueError("Timeout keys can only be one of the following: implicit, pageLoad, script")
class _ProxyDescriptor:
"""Descriptor for proxy property access.
Returns:
Proxy if set, otherwise None.
"""
def __init__(self, name):
self.name = name
def __get__(self, obj, cls):
return obj._proxy
def __set__(self, obj, value):
if not isinstance(value, Proxy):
raise InvalidArgumentException("Only Proxy objects can be passed in.")View on GitHub (pinned to aa36b38e69)
Solutions
- Use only the keys 'implicit', 'pageLoad', 'script' (camelCase as shown).
- Pass a dict, never a bare int or None.
- If setting individual timeouts, prefer driver.implicitly_wait() / driver.set_script_timeout() / driver.set_page_load_timeout() instead.
Example fix
# before
options.timeouts = {'page_load': 3000} # wrong key -> ValueError
# after
options.timeouts = {'pageLoad': 3000, 'implicit': 0} Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {'implicit','pageLoad','script'}
if not isinstance(value, dict):
raise TypeError('timeouts must be a dict')
bad = set(value) - ALLOWED
if bad:
raise ValueError(f'Invalid timeout keys: {bad}; allowed {sorted(ALLOWED)}')
options.timeouts = value Type guard
ALLOWED = {'implicit','pageLoad','script'}
def is_valid_timeouts(v) -> bool:
return isinstance(v, dict) and set(v).issubset(ALLOWED) Try / catch
try:
options.timeouts = value
except (ValueError, AttributeError):
options.timeouts = {'pageLoad': value} if isinstance(value, int) else {} Prevention
- Use camelCase keys: pageLoad, not page_load.
- Always pass a dict, never a scalar.
- Prefer the dedicated timeout methods for single values.
When it happens
Trigger: Setting options.timeouts = {'implicit': 5} (correct), but options.timeouts = {'implicit_wait': 5} or {'page_load': 3000} raises. Also passing None or a non-dict crashes on .keys() with AttributeError rather than the friendly ValueError.
Common situations: Using snake_case keys ('page_load', 'implicit_wait') instead of camelCase ('pageLoad'). Passing a single int instead of a dict. Confusing unit expectations (these are raw capability values).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Strategy can only be one of the following: normal, eager, no
- Behavior can only be one of the following: dismiss, accept,
- no capabilities provided for merge
- Capability keys must be strings: ${typeof key}
- argument can not be null
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/06830de48e6a5995.
Report an issue: GitHub.