{"record":{"id":"06830de48e6a5995","repo":"SeleniumHQ/selenium","slug":"timeout-keys-can-only-be-one-of-the-following-imp","errorCode":null,"errorMessage":"Timeout keys can only be one of the following: implicit, pageLoad, script","messagePattern":"Timeout keys can only be one of the following: implicit, pageLoad, script","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py/selenium/webdriver/common/options.py","lineNumber":141,"sourceCode":"\n    Args:\n        timeouts: values in milliseconds for implicit wait, page load and script timeout\n\n    Returns:\n        Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)\n    \"\"\"\n\n    def __init__(self, name):\n        self.name = name\n\n    def __get__(self, obj, cls):\n        return obj._caps.get(self.name)\n\n    def __set__(self, obj, value):\n        if all(x in (\"implicit\", \"pageLoad\", \"script\") for x in value.keys()):\n            obj.set_capability(self.name, value)\n        else:\n            raise ValueError(\"Timeout keys can only be one of the following: implicit, pageLoad, script\")\n\n\nclass _ProxyDescriptor:\n    \"\"\"Descriptor for proxy property access.\n\n    Returns:\n        Proxy if set, otherwise None.\n    \"\"\"\n\n    def __init__(self, name):\n        self.name = name\n\n    def __get__(self, obj, cls):\n        return obj._proxy\n\n    def __set__(self, obj, value):\n        if not isinstance(value, Proxy):\n            raise InvalidArgumentException(\"Only Proxy objects can be passed in.\")","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/common/options.py#L123-L159","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"# before\noptions.timeouts = {'page_load': 3000}  # wrong key -> ValueError\n\n# after\noptions.timeouts = {'pageLoad': 3000, 'implicit': 0}","handlingStrategy":"validation","validationCode":"ALLOWED = {'implicit','pageLoad','script'}\nif not isinstance(value, dict):\n    raise TypeError('timeouts must be a dict')\nbad = set(value) - ALLOWED\nif bad:\n    raise ValueError(f'Invalid timeout keys: {bad}; allowed {sorted(ALLOWED)}')\noptions.timeouts = value","typeGuard":"ALLOWED = {'implicit','pageLoad','script'}\ndef is_valid_timeouts(v) -> bool:\n    return isinstance(v, dict) and set(v).issubset(ALLOWED)","tryCatchPattern":"try:\n    options.timeouts = value\nexcept (ValueError, AttributeError):\n    options.timeouts = {'pageLoad': value} if isinstance(value, int) else {}","preventionTips":["Use camelCase keys: pageLoad, not page_load.","Always pass a dict, never a scalar.","Prefer the dedicated timeout methods for single values."],"tags":["options","timeouts","validation","capabilities"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}