SeleniumHQ/selenium · error · Error::WebDriverError

expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.ins

Error message

expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.inspect}

What it means

Raised by Firefox::Extension#create_root (Error::WebDriverError) when the path is a file (not a directory) but its extension is not in Zipper::EXTENSIONS (i.e. not .zip or .xpi). The extension loader can only unpack .zip/.xpi archives or use an already-extracted directory.

Source

Thrown at rb/lib/selenium/webdriver/firefox/extension.rb:55

        def write_to(extensions_dir)
          root_dir = create_root
          ext_path = File.join extensions_dir, read_id(root_dir)

          FileUtils.rm_rf ext_path
          FileUtils.mkdir_p File.dirname(ext_path), mode: 0o700
          FileUtils.cp_r root_dir, ext_path

          FileReaper.reap(root_dir) if @should_reap_root
        end

        private

        def create_root
          if File.directory? @path
            @path
          else
            unless Zipper::EXTENSIONS.include? File.extname(@path)
              raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.inspect}"
            end

            @should_reap_root = true
            Zipper.unzip(@path)
          end
        end

        def read_id(directory)
          read_id_from_install_rdf(directory) || read_id_from_manifest_json(directory)
        end

        def read_id_from_install_rdf(directory)
          rdf_path = File.join(directory, 'install.rdf')
          return unless File.exist?(rdf_path)

          doc = REXML::Document.new(File.read(rdf_path))
          namespace = doc.root.namespaces.key(NAMESPACE)

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Package the extension as an .xpi or .zip archive, or pass the unpacked extension directory.
  2. If you have a directory build, point add_extension at the directory rather than a file inside it.
  3. Re-download/re-export the addon in the correct format (.xpi for Firefox).

Example fix

// before
profile.add_extension('build/extension.crx')

// after
# export as xpi, or pass the unpacked dir
profile.add_extension('build/extension.xpi')
# or
profile.add_extension('build/unpacked_extension_dir')
Defensive patterns

Strategy: validation

Validate before calling

ext = File.extname(path)
if File.directory?(path) || %w[.zip .xpi].include?(ext)
  profile.add_extension(path)
else
  raise "extension must be .zip/.xpi or a directory, got #{ext.inspect}"
end

Prevention

When it happens

Trigger: Passing a .crx, .tar.gz, .json, or extensionless file to add_extension; downloading an addon in a format Firefox/Selenium cannot unpack; pointing at a manifest.json file directly instead of the packaged archive or directory.

Common situations: Trying to install a Chrome .crx into Firefox; renaming an archive incorrectly; passing a URL instead of a local archive path.

Related errors


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