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
- Inspect the wrapped exception message in the AddonFormatError to identify the missing key or I/O error
- Validate the manifest.json structure manually: ensure manifest['applications']['gecko']['id'] or manifest['version'] exist
- 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
- Validate manifest.json has 'version' and 'applications.gecko.id' fields
- Use well-formed XPIs built by Mozilla web-ext tooling
- Inspect the wrapped exception message to find the specific missing key
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
- Could not find add-on ID for ${extension}
- Add-on path does not exist: {addon_path}
- Add-on path is neither an XPI nor a directory: {addon_path}
- Add-on id could not be found.
- cannot locate extension id in #{rdf_path}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/30802059926ece67.
Report an issue: GitHub.