{"record":{"id":"664b641563ef9ff2","repo":"SeleniumHQ/selenium","slug":"unable-to-obtain-service-class-executable","errorCode":null,"errorMessage":"Unable to obtain #{@service.class::EXECUTABLE}","messagePattern":"Unable to obtain #(.+?)","errorType":"exception","errorClass":"Error::NoSuchDriverError","httpStatus":null,"severity":"critical","filePath":"rb/lib/selenium/webdriver/common/driver_finder.rb","lineNumber":57,"sourceCode":"\n      def driver_path\n        paths[:driver_path]\n      end\n\n      def browser_path?\n        !browser_path.nil? && !browser_path.empty?\n      end\n\n      private\n\n      def paths\n        @paths ||= begin\n          path = @service.executable_path || env_path || class_path\n          path ? paths_from_service(path) : paths_from_manager\n        rescue StandardError => e\n          WebDriver.logger.error(\"Exception occurred: #{e.message}\", id: :driver_finder)\n          WebDriver.logger.error(\"Backtrace:\\n\\t#{e.backtrace&.join(\"\\n\\t\")}\", id: :driver_finder)\n          raise Error::NoSuchDriverError, \"Unable to obtain #{@service.class::EXECUTABLE}\"\n        end\n      end\n\n      def env_path\n        ENV.fetch(@service.class::DRIVER_PATH_ENV_KEY, nil)\n      end\n\n      def class_path\n        path = @service.class.driver_path\n        path.is_a?(Proc) ? path.call : path\n      end\n\n      def paths_from_service(path)\n        exe = @service.class::EXECUTABLE\n        WebDriver.logger.debug(\"Skipping Selenium Manager; path to #{exe} specified in service class: #{path}\",\n                               id: :driver_finder)\n        Platform.assert_executable(path)\n        {driver_path: path}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/driver_finder.rb#L39-L75","documentation":"Raised as Error::NoSuchDriverError from DriverFinder#paths when locating the driver (or browser) executable fails for ANY reason. The rescue catches StandardError broadly, logs the real message at error level with id: :driver_finder, then re-raises this generic message naming @service.class::EXECUTABLE (e.g. 'chromedriver', 'geckodriver'). The underlying cause is hidden in the logged exception, not in the raised message.","triggerScenarios":"Constructing a Driver (Selenium::WebDriver.for(:chrome), etc.) triggers DriverFinder.new(options, service).driver_path. It fails when: (a) SeleniumManager.binary_paths returns no/invalid path (no network, browser not installed, unsupported browser version), (b) an explicit path from service.executable_path / DRIVER_PATH_ENV_KEY / Service.driver_path is missing or not executable (Platform.assert_executable raises), or (c) the configured Proc in driver_path raises.","commonSituations":"CI/image without the browser installed; Selenium Manager cannot reach its download mirror (air-gapped / proxy); a pinned driver path points at a stale or non-executable file after an OS update or docker layer change; upgrading the browser past the last driver Selenium Manager knows about; on Windows a path with a missing .exe extension or lacking execute permission.","solutions":["Re-run with WebDriver.logger.level = :debug (or set SELENIUM_LOG_LEVEL=debug); the rescue logs 'Exception occurred: <real message>' and the backtrace under id: :driver_finder — read that line first, it states the true cause.","Pre-place the driver and point at it explicitly: set the service env var (e.g. SELENIUM_CHROMEDRIVER_PATH=/abs/path/chromedriver) or Service.executable_path, and confirm the file exists, is non-empty, and has the executable bit (chmod +x).","Ensure the target browser is actually installed and discoverable on PATH, and that Selenium Manager (bundled binary under selenium-manager) can run and reach its download host — check network/proxy/firewall in air-gapped CI.","Match versions: the driver major version must be compatible with the installed browser major version; in pinned-driver setups downgrade/upgrade the driver to match."],"exampleFix":"// before\noptions = Selenium::WebDriver::Chrome::Options.new\ndriver = Selenium::WebDriver.for(:chrome, options: options) # => NoSuchDriverError: Unable to obtain chromedriver\n\n# after\npath = \"/usr/local/bin/chromedriver\"\nraise \"missing #{path}\" unless File.executable?(path)\nservice = Selenium::WebDriver::Service.chrome(executable_path: path)\ndriver = Selenium::WebDriver.for(:chrome, options: options, service: service)","handlingStrategy":"validation","validationCode":"# Run before Selenium::WebDriver.for(...)\nservice = Selenium::WebDriver::Service.chrome\ndriver_path = ENV[service.class::DRIVER_PATH_ENV_KEY] || service.class.driver_path\ndriver_path = driver_path.call if driver_path.is_a?(Proc)\nif driver_path\n  raise \"driver not executable: #{driver_path}\" unless File.file?(driver_path) && File.executable?(driver_path)\nend\n# Let Selenium Manager resolve only when no explicit path is set; check the browser binary too:\nbrowser = Selenium::WebDriver::Chrome.path || `which google-chrome 2>/dev/null`.strip\nraise \"chrome binary not found on PATH\" if browser.empty?","typeGuard":null,"tryCatchPattern":"begin\n  driver = Selenium::WebDriver.for(:chrome, options: options)\nrescue Selenium::WebDriver::Error::NoSuchDriverError => e\n  WebDriver.logger.replay(id: :driver_finder) if WebDriver.logger.respond_to?(:replay)\n  raise \"Driver init failed (#{e.message}); run with SELENIUM_LOG_LEVEL=debug to see the underlying cause\"\nend","preventionTips":["Pin a known-good driver/browser pair in CI images and set SELENIUM_*_PATH env vars to absolute, executable paths.","In air-gapped CI, pre-download drivers and disable Selenium Manager network access by pointing services at the local files.","Run with SELENIUM_LOG_LEVEL=debug during driver setup so the underlying 'Exception occurred:' line is visible before this generic error."],"tags":["driver-setup","selenium-manager","ruby","environment","executable"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}