SeleniumHQ/selenium · error · TypeError
log_level must be one of: {', '.join(levels)}
Error message
log_level must be one of: {', '.join(levels)} What it means
Raised by the `log_level` property setter on a Selenium server runner when the assigned value is not one of the seven recognized Java logging levels (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST). The library guards the value before storing it so the spawned `java -jar` process receives a legal `--log-level` argument. It surfaces as a TypeError because the bad input is a programmer error, not a runtime condition.
Source
Thrown at py/selenium/webdriver/remote/server.py:136
def version(self):
return self._version
@version.setter
def version(self, version):
if version:
if not re.match(r"^\d+\.\d+\.\d+$", str(version)):
raise TypeError(f"{__class__.__name__}.__init__() got an invalid version: '{version}'")
self._version = version
@property
def log_level(self):
return self._log_level
@log_level.setter
def log_level(self, log_level):
levels = ("SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST")
if log_level not in levels:
raise TypeError(f"log_level must be one of: {', '.join(levels)}")
self._log_level = log_level
@property
def env(self):
return self._env
@env.setter
def env(self, env):
if env is not None and not isinstance(env, collections.abc.Mapping):
raise TypeError("env must be a mapping of environment variables")
self._env = env
@property
def java_path(self):
return self._java_path
@java_path.setter
def java_path(self, java_path):View on GitHub (pinned to aa36b38e69)
Solutions
- Use one of the exact canonical strings: 'SEVERE', 'WARNING', 'INFO', 'CONFIG', 'FINE', 'FINER', 'FINEST'.
- If sourcing the level from config, validate it against the allowed set before assigning.
- Map your own level vocabulary to these strings rather than passing foreign level names.
Example fix
# before server.log_level = 'debug' # after server.log_level = 'FINE'
Defensive patterns
Strategy: validation
Validate before calling
LEVELS = ('SEVERE','WARNING','INFO','CONFIG','FINE','FINER','FINEST')
if level not in LEVELS:
raise ValueError(f'bad log level {level!r}; choose from {LEVELS}')
server.log_level = level Type guard
def is_valid_log_level(v) -> bool:
return isinstance(v, str) and v in ('SEVERE','WARNING','INFO','CONFIG','FINE','FINER','FINEST') Prevention
- Treat the level as an enum, not free text; centralize the allowed set.
- Add a unit test that asserts the configured level is in the canonical tuple.
When it happens
Trigger: Assigning `server.log_level = 'DEBUG'` (or any casing/typo like 'info ' with trailing space, 'Warn', 'verbose') triggers it. The setter compares membership against the exact tuple, so only the exact canonical strings pass.
Common situations: Copy-pasting a level name from another logging framework (Python's logging.DEBUG, log4j DEBUG/TRACE) or from documentation that uses lowercase. Passing an integer level code instead of the string name.
Related errors
- Level must be >= 0
- env must be a mapping of environment variables
- Can't find java executable located at {java_path}
- Invalid URL: ${aUrl}
- no capabilities provided for merge
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/b1f1c8e571e2476b.
Report an issue: GitHub.