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

  1. Unzip the archive and confirm manifest.json is at the root level.
  2. Rebuild the extension so manifest.json sits at the archive root.
  3. Use a valid Firefox .xpi from AMO or your build tool (web-ext).
  4. 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

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


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