SeleniumHQ/selenium · error · AddonFormatError

{str(e)}

Error message

{str(e)}

What it means

Raised as AddonFormatError when the first try block (reading the addon archive or directory for manifest/install.rdf content) encounters an OSError or KeyError. The original exception message is wrapped into the AddonFormatError so the underlying I/O or key-missing problem is surfaced. This is a re-raise, chaining from the original via sys.exc_info()[2].

Source

Thrown at py/selenium/webdriver/firefox/firefox_profile.py:295

        try:
            if zipfile.is_zipfile(addon_path):
                with zipfile.ZipFile(addon_path, "r") as compressed_file:
                    if "manifest.json" in compressed_file.namelist():
                        return parse_manifest_json(compressed_file.read("manifest.json"))

                    manifest = compressed_file.read("install.rdf")
            elif os.path.isdir(addon_path):
                manifest_json_filename = os.path.join(addon_path, "manifest.json")
                if os.path.exists(manifest_json_filename):
                    with open(manifest_json_filename, encoding="utf-8") as f:
                        return parse_manifest_json(f.read())

                with open(os.path.join(addon_path, "install.rdf"), encoding="utf-8") as f:
                    manifest = f.read()
            else:
                raise OSError(f"Add-on path is neither an XPI nor a directory: {addon_path}")
        except (OSError, KeyError) as e:
            raise AddonFormatError(str(e), sys.exc_info()[2])

        try:
            doc = minidom.parseString(manifest)

            # Get the namespaces abbreviations
            em = get_namespace_id(doc, "http://www.mozilla.org/2004/em-rdf#")
            rdf = get_namespace_id(doc, "http://www.w3.org/1999/02/22-rdf-syntax-ns#")

            description = doc.getElementsByTagName(rdf + "Description").item(0)
            if not description:
                description = doc.getElementsByTagName("Description").item(0)
            for node in description.childNodes:
                # Remove the namespace prefix from the tag for comparison
                entry = node.nodeName.replace(em, "")
                if entry in details:
                    details.update({entry: get_text(node)})
            if not details.get("id"):
                for i in range(description.attributes.length):

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Inspect the wrapped exception message in the AddonFormatError to identify the missing key or I/O error
  2. Validate the manifest.json structure manually: ensure manifest['applications']['gecko']['id'] or manifest['version'] exist
  3. Use a standard, well-formed .xpi built by Mozilla's web-ext tooling

Example fix

// before
profile.add_extension('broken-addon.xpi')
# AddonFormatError: 'version'

// after
# Fix the manifest.json to include required fields:
# {"manifest_version": 2, "version": "1.0", "applications": {"gecko": {"id": "my@addon"}}}
Defensive patterns

Strategy: try-catch

Validate before calling

import json, zipfile
with zipfile.ZipFile(addon_path) as z:
    if 'manifest.json' in z.namelist():
        manifest = json.loads(z.read('manifest.json'))
        assert manifest.get('version'), 'manifest.json missing version'
        assert manifest.get('applications', {}).get('gecko', {}).get('id') or manifest.get('name'), 'manifest missing id/name'

Try / catch

from selenium.common.exceptions import AddonFormatError
try:
    profile.add_extension(addon_path)
except AddonFormatError as e:
    print(f'Addon format error: {e}')
    # inspect e to find the missing key or I/O issue

Prevention

When it happens

Trigger: A .xpi whose manifest.json is missing the 'applications' key or other expected fields (KeyError), or an OSError from reading a file inside a malformed zip. The install.rdf read can also fail with KeyError on malformed structure.

Common situations: Old or non-standard Firefox extensions that don't follow the standard manifest.json schema. XPI files built with non-standard tooling. Manifests using 'browser_specific_settings' instead of 'applications'.

Related errors


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