{"record":{"id":"30802059926ece67","repo":"SeleniumHQ/selenium","slug":"str-e","errorCode":null,"errorMessage":"{str(e)}","messagePattern":"\\{str\\(e\\)\\}","errorType":"exception","errorClass":"AddonFormatError","httpStatus":null,"severity":"error","filePath":"py/selenium/webdriver/firefox/firefox_profile.py","lineNumber":295,"sourceCode":"        try:\n            if zipfile.is_zipfile(addon_path):\n                with zipfile.ZipFile(addon_path, \"r\") as compressed_file:\n                    if \"manifest.json\" in compressed_file.namelist():\n                        return parse_manifest_json(compressed_file.read(\"manifest.json\"))\n\n                    manifest = compressed_file.read(\"install.rdf\")\n            elif os.path.isdir(addon_path):\n                manifest_json_filename = os.path.join(addon_path, \"manifest.json\")\n                if os.path.exists(manifest_json_filename):\n                    with open(manifest_json_filename, encoding=\"utf-8\") as f:\n                        return parse_manifest_json(f.read())\n\n                with open(os.path.join(addon_path, \"install.rdf\"), encoding=\"utf-8\") as f:\n                    manifest = f.read()\n            else:\n                raise OSError(f\"Add-on path is neither an XPI nor a directory: {addon_path}\")\n        except (OSError, KeyError) as e:\n            raise AddonFormatError(str(e), sys.exc_info()[2])\n\n        try:\n            doc = minidom.parseString(manifest)\n\n            # Get the namespaces abbreviations\n            em = get_namespace_id(doc, \"http://www.mozilla.org/2004/em-rdf#\")\n            rdf = get_namespace_id(doc, \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\")\n\n            description = doc.getElementsByTagName(rdf + \"Description\").item(0)\n            if not description:\n                description = doc.getElementsByTagName(\"Description\").item(0)\n            for node in description.childNodes:\n                # Remove the namespace prefix from the tag for comparison\n                entry = node.nodeName.replace(em, \"\")\n                if entry in details:\n                    details.update({entry: get_text(node)})\n            if not details.get(\"id\"):\n                for i in range(description.attributes.length):","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/firefox/firefox_profile.py#L277-L313","documentation":"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].","triggerScenarios":"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.","commonSituations":"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'.","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"],"exampleFix":"// before\nprofile.add_extension('broken-addon.xpi')\n# AddonFormatError: 'version'\n\n// after\n# Fix the manifest.json to include required fields:\n# {\"manifest_version\": 2, \"version\": \"1.0\", \"applications\": {\"gecko\": {\"id\": \"my@addon\"}}}","handlingStrategy":"try-catch","validationCode":"import json, zipfile\nwith zipfile.ZipFile(addon_path) as z:\n    if 'manifest.json' in z.namelist():\n        manifest = json.loads(z.read('manifest.json'))\n        assert manifest.get('version'), 'manifest.json missing version'\n        assert manifest.get('applications', {}).get('gecko', {}).get('id') or manifest.get('name'), 'manifest missing id/name'","typeGuard":null,"tryCatchPattern":"from selenium.common.exceptions import AddonFormatError\ntry:\n    profile.add_extension(addon_path)\nexcept AddonFormatError as e:\n    print(f'Addon format error: {e}')\n    # inspect e to find the missing key or I/O issue","preventionTips":["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"],"tags":["firefox","addon","manifest","exception-chaining","profile"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}