SeleniumHQ/selenium · error · TypeError

Binary Location Must be a String

Error message

Binary Location Must be a String

What it means

Raised as TypeError by the FirefoxOptions.binary_location setter when the value is not a Python str. The setter strictly checks isinstance(value, str) because the binary location is passed to Firefox as a filesystem path, and non-string types would cause failures later in the driver launch process.

Source

Thrown at py/selenium/webdriver/firefox/options.py:57

        super().__init__()
        self._binary_location = ""
        self._preferences: dict = {}
        # https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/.
        # Enable BiDi only
        self._preferences["remote.active-protocols"] = 1
        self._profile: FirefoxProfile | None = None
        self.log = Log()

    @property
    def binary_location(self) -> str:
        """Returns the location of the binary."""
        return self._binary_location

    @binary_location.setter
    def binary_location(self, value: str) -> None:
        """Sets the location of the browser binary by string."""
        if not isinstance(value, str):
            raise TypeError(self.BINARY_LOCATION_ERROR)
        self._binary_location = value

    @property
    def preferences(self) -> dict:
        """Returns a dict of preferences."""
        return self._preferences

    def set_preference(self, name: str, value: str | int | bool):
        """Sets a preference."""
        self._preferences[name] = value

    @property
    def profile(self) -> FirefoxProfile | None:
        """Returns the Firefox profile to use."""
        return self._profile

    @profile.setter
    def profile(self, new_profile: str | FirefoxProfile) -> None:

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Convert pathlib.Path to string: options.binary_location = str(path)
  2. If no override is needed, do not set binary_location at all (leave the default empty string)
  3. Ensure the value is a plain Python str before assignment

Example fix

// before
from pathlib import Path
options.binary_location = Path('/usr/bin/firefox')

// after
from pathlib import Path
options.binary_location = str(Path('/usr/bin/firefox'))
Defensive patterns

Strategy: type-guard

Validate before calling

from pathlib import Path
binary = Path('/usr/bin/firefox')
options.binary_location = str(binary) if isinstance(binary, Path) else binary

Type guard

def is_str(v) -> bool:
    return isinstance(v, str)

Try / catch

try:
    options.binary_location = value
except TypeError:
    options.binary_location = str(value)

Prevention

When it happens

Trigger: Assigning options.binary_location = Path('/usr/bin/firefox') (a pathlib.Path), or options.binary_location = None, or options.binary_location = b'/usr/bin/firefox' (bytes) triggers the TypeError.

Common situations: Developers using pathlib.Path objects (common in modern Python) without converting to string. Configuration from JSON that deserializes as non-string types. Passing None when no binary override is intended.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/8764b318a5b4a599. Report an issue: GitHub.