{"record":{"id":"c8a0bd0de4abda94","repo":"SeleniumHQ/selenium","slug":"compound-class-names-are-not-allowed","errorCode":null,"errorMessage":"Compound class names are not allowed.","messagePattern":"Compound class names are not allowed\\.","errorType":"exception","errorClass":"InvalidSelectorException","httpStatus":null,"severity":"error","filePath":"py/selenium/webdriver/remote/locator_converter.py","lineNumber":29,"sourceCode":"# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n\nfrom selenium.common.exceptions import InvalidSelectorException\nfrom selenium.webdriver.common.by import By\n\n\nclass LocatorConverter:\n    def convert(self, by, value):\n        # Default conversion logic\n        if by == By.ID:\n            return By.CSS_SELECTOR, f'[id=\"{value}\"]'\n        elif by == By.CLASS_NAME:\n            if value and any(char.isspace() for char in value.strip()):\n                raise InvalidSelectorException(\"Compound class names are not allowed.\")\n            return By.CSS_SELECTOR, f\".{value}\"\n        elif by == By.NAME:\n            return By.CSS_SELECTOR, f'[name=\"{value}\"]'\n        return by, value\n","sourceCodeStart":11,"sourceCodeEnd":34,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/remote/locator_converter.py#L11-L34","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ndriver.find_element(By.CLASS_NAME, 'btn primary')\n\n// after\ndriver.find_element(By.CSS_SELECTOR, '.btn.primary')","handlingStrategy":"validation","validationCode":"by, value = By.CLASS_NAME, 'btn primary'\nif by == By.CLASS_NAME and value and any(c.isspace() for c in value.strip()):\n    value = '.'.join(f'.{c}' for c in value.split())\n    by = By.CSS_SELECTOR\ndriver.find_element(by, value)","typeGuard":"def is_compound_class_name(value: str) -> bool:\n    return bool(value and any(c.isspace() for c in value.strip()))","tryCatchPattern":"from selenium.common.exceptions import InvalidSelectorException\ntry:\n    driver.find_element(By.CLASS_NAME, class_str)\nexcept InvalidSelectorException:\n    css = ''.join(f'.{c}' for c in class_str.split())\n    driver.find_element(By.CSS_SELECTOR, css)","preventionTips":["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"],"tags":["remote","locator","css-selector","class-name","invalid-selector"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}