SeleniumHQ/selenium · error · InvalidSelectorException
Compound class names are not allowed.
Error message
Compound class names are not allowed.
What it means
Raised as InvalidSelectorException by LocatorConverter.convert when a By.CLASS_NAME locator value contains internal whitespace (after stripping leading/trailing whitespace), which CSS class selectors cannot represent. A compound class name like 'btn primary' maps to multiple CSS classes (.btn.primary) and the converter refuses to silently guess the correct transformation.
Source
Thrown at py/selenium/webdriver/remote/locator_converter.py:29
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from selenium.common.exceptions import InvalidSelectorException
from selenium.webdriver.common.by import By
class LocatorConverter:
def convert(self, by, value):
# Default conversion logic
if by == By.ID:
return By.CSS_SELECTOR, f'[id="{value}"]'
elif by == By.CLASS_NAME:
if value and any(char.isspace() for char in value.strip()):
raise InvalidSelectorException("Compound class names are not allowed.")
return By.CSS_SELECTOR, f".{value}"
elif by == By.NAME:
return By.CSS_SELECTOR, f'[name="{value}"]'
return by, value
View on GitHub (pinned to aa36b38e69)
Solutions
- Use By.CSS_SELECTOR for compound classes: driver.find_element(By.CSS_SELECTOR, '.btn.primary')
- Select a single class from the compound name if only one is needed
- Use By.XPATH with contains(@class, 'className') for partial matching
Example fix
// before driver.find_element(By.CLASS_NAME, 'btn primary') // after driver.find_element(By.CSS_SELECTOR, '.btn.primary')
Defensive patterns
Strategy: validation
Validate before calling
by, value = By.CLASS_NAME, 'btn primary'
if by == By.CLASS_NAME and value and any(c.isspace() for c in value.strip()):
value = '.'.join(f'.{c}' for c in value.split())
by = By.CSS_SELECTOR
driver.find_element(by, value) Type guard
def is_compound_class_name(value: str) -> bool:
return bool(value and any(c.isspace() for c in value.strip())) Try / catch
from selenium.common.exceptions import InvalidSelectorException
try:
driver.find_element(By.CLASS_NAME, class_str)
except InvalidSelectorException:
css = ''.join(f'.{c}' for c in class_str.split())
driver.find_element(By.CSS_SELECTOR, css) Prevention
- Use By.CSS_SELECTOR with dot-joined classes for compound names
- Check for spaces in class names before using By.CLASS_NAME
- Select a single class name when only one class is needed
When it happens
Trigger: Calling driver.find_element(By.CLASS_NAME, 'btn primary') or any By.CLASS_NAME value with a space inside. The converter checks value.strip() for any whitespace character and raises if found.
Common situations: Web elements with multiple CSS classes where the developer passes the full class attribute string. Copy-pasting class names from HTML that contain spaces. Using By.CLASS_NAME when By.CSS_SELECTOR is needed.
Related errors
- Invalid URL: ${aUrl}
- Do not know how to build driver: ${browser}; did you forget
- input must be a string
- Invalid locator
- Unknown error: ${JSON.stringify(data)}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/c8a0bd0de4abda94.
Report an issue: GitHub.