SeleniumHQ/selenium · error · TypeError

no_proxy list must contain only strings

Error message

no_proxy list must contain only strings

What it means

When converting proxy settings to BiDi format (to_bidi_dict), if noProxy is a list, every element must be a string. A list containing a non-string (int, None, dict) raises TypeError. This runs only when proxyType is 'manual'.

Source

Thrown at py/selenium/webdriver/common/proxy.py:211

        proxy_type = self.proxyType["string"].lower()
        result = {"proxyType": proxy_type}

        if proxy_type == "manual":
            if self.httpProxy:
                result["httpProxy"] = self.httpProxy
            if self.sslProxy:
                result["sslProxy"] = self.sslProxy
            if self.socksProxy:
                result["socksProxy"] = self.socksProxy
            if self.socksVersion is not None:
                result["socksVersion"] = self.socksVersion
            if self.noProxy:
                # Convert comma-separated string to list
                if isinstance(self.noProxy, str):
                    result["noProxy"] = [host.strip() for host in self.noProxy.split(",") if host.strip()]
                elif isinstance(self.noProxy, list):
                    if not all(isinstance(h, str) for h in self.noProxy):
                        raise TypeError("no_proxy list must contain only strings")
                    result["noProxy"] = self.noProxy
                else:
                    raise TypeError("no_proxy must be a comma-separated string or a list of strings")

        elif proxy_type == "pac":
            if self.proxyAutoconfigUrl:
                result["proxyAutoconfigUrl"] = self.proxyAutoconfigUrl

        return result

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Ensure every element of the no_proxy list is a string: [str(h) for h in hosts].
  2. Store full 'host:port' strings rather than separate ints.

Example fix

# before
proxy.no_proxy = ['localhost', 8080]  # int in list
proxy.to_bidi_dict()  # raises TypeError

# after
proxy.no_proxy = ['localhost', '8080']
# or normalize
proxy.no_proxy = [str(h) for h in raw_hosts]
Defensive patterns

Strategy: validation

Validate before calling

if isinstance(no_proxy, list):
    no_proxy = [str(h) for h in no_proxy]
proxy.no_proxy = no_proxy

Type guard

def is_str_list(v) -> bool:
    return isinstance(v, list) and all(isinstance(h, str) for h in v)

Try / catch

try:
    proxy.to_bidi_dict()
except TypeError:
    proxy.no_proxy = [str(h) for h in proxy.no_proxy]
    proxy.to_bidi_dict()

Prevention

When it happens

Trigger: Setting proxy.no_proxy = ['localhost', 8080] or proxy.no_proxy = [None, 'host'] then calling proxy.to_bidi_dict(). The list itself is accepted by the setter (MANUAL descriptor) but fails at BiDi conversion.

Common situations: Mixing ports into the bypass list as ints. Building the list from mixed-type config. Parsing a bypass string into tokens that include numeric ports.

Related errors


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