SeleniumHQ/selenium · error · AddonFormatError
Couldn't find manifest.json in ${extension}
Error message
Couldn't find manifest.json in ${extension} What it means
Thrown by installExtension() in firefox.js when the provided .xpi or .zip archive does not contain a manifest.json entry at its root. Firefox extensions are required to include this manifest. The archive is loaded via zip.load() and checked with archive.has('manifest.json').
Source
Thrown at javascript/selenium-webdriver/firefox.js:155
}
}
/**
* Installs an extension to the given directory.
* @param {string} extension Path to the xpi extension file to install.
* @param {string} dir Path to the directory to install the extension in.
* @return {!Promise<string>} A promise for the add-on ID once
* installed.
*/
async function installExtension(extension, dir) {
const ext = extension.slice(-4)
if (ext !== '.xpi' && ext !== '.zip') {
throw Error('File name does not end in ".zip" or ".xpi": ' + ext)
}
let archive = await zip.load(extension)
if (!archive.has('manifest.json')) {
throw new AddonFormatError(`Couldn't find manifest.json in ${extension}`)
}
let buf = await archive.getFile('manifest.json')
let parsedJSON = JSON.parse(buf.toString('utf8'))
let { browser_specific_settings } =
/** @type {{browser_specific_settings:{gecko:{id:string}}}} */
parsedJSON
if (browser_specific_settings && browser_specific_settings.gecko) {
/* browser_specific_settings is an alternative to applications
* It is meant to facilitate cross-browser plugins since Firefox48
* see https://bugzilla.mozilla.org/show_bug.cgi?id=1262005
*/
parsedJSON.applications = browser_specific_settings
}
let { applications } =View on GitHub (pinned to aa36b38e69)
Solutions
- Unzip the archive and confirm manifest.json is at the root level.
- Rebuild the extension so manifest.json sits at the archive root.
- Use a valid Firefox .xpi from AMO or your build tool (web-ext).
- Ensure you are passing a Firefox extension, not a Chrome extension.
Defensive patterns
Strategy: validation
Validate before calling
const AdmZip = require('adm-zip') // or equivalent
async function validateExtensionArchive(extensionPath) {
const archive = await zip.load(extensionPath)
if (!archive.has('manifest.json')) {
throw new Error(`Archive ${extensionPath} has no root manifest.json`)
}
return true
} Prevention
- Inspect the archive contents (unzip -l) before installing to confirm root-level manifest.json.
- Use web-ext or a proper Firefox build tool to produce valid .xpi files.
- Do not pass Chrome extensions (.crx) to Firefox installExtension().
- Ensure manifest.json is at the archive root, not in a subdirectory.
When it happens
Trigger: Passing a zip/xpi that is not a Firefox extension (e.g., a Chrome .crx renamed, a generic zip). The archive has manifest.json nested in a subdirectory rather than at root. A corrupted or incomplete archive.
Common situations: Trying to install a Chrome extension in Firefox; extension build pipeline outputting the wrong structure; selecting the wrong file from a build directory; manifest.json placed in a subfolder during packaging.
Related errors
- Could not find add-on ID for ${extension}
- expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.ins
- Add-on id could not be found.
- could not find extension at #{path.inspect}
- cannot locate extension id in #{rdf_path}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/5b9d8881f6d67886.
Report an issue: GitHub.