{"record":{"id":"af81cd7b5566d336","repo":"browser-use/browser-use","slug":"no-manifest-json-found-in-extension","errorCode":null,"errorMessage":"No manifest.json found in extension","messagePattern":"No manifest\\.json found in extension","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"browser_use/browser/profile.py","lineNumber":1201,"sourceCode":"\t\timport os\n\t\timport zipfile\n\n\t\t# Remove existing directory\n\t\tif extract_dir.exists():\n\t\t\timport shutil\n\n\t\t\tshutil.rmtree(extract_dir)\n\n\t\textract_dir.mkdir(parents=True, exist_ok=True)\n\n\t\ttry:\n\t\t\t# CRX files are ZIP files with a header, try to extract as ZIP\n\t\t\twith zipfile.ZipFile(crx_path, 'r') as zip_ref:\n\t\t\t\tzip_ref.extractall(extract_dir)\n\n\t\t\t# Verify manifest exists\n\t\t\tif not (extract_dir / 'manifest.json').exists():\n\t\t\t\traise Exception('No manifest.json found in extension')\n\n\t\texcept zipfile.BadZipFile:\n\t\t\t# CRX files have a header before the ZIP data\n\t\t\t# Skip the CRX header and extract the ZIP part\n\t\t\twith open(crx_path, 'rb') as f:\n\t\t\t\t# Read CRX header to find ZIP start\n\t\t\t\tmagic = f.read(4)\n\t\t\t\tif magic != b'Cr24':\n\t\t\t\t\traise Exception('Invalid CRX file format')\n\n\t\t\t\tversion = int.from_bytes(f.read(4), 'little')\n\t\t\t\tif version == 2:\n\t\t\t\t\tpubkey_len = int.from_bytes(f.read(4), 'little')\n\t\t\t\t\tsig_len = int.from_bytes(f.read(4), 'little')\n\t\t\t\t\tf.seek(16 + pubkey_len + sig_len)  # Skip to ZIP data\n\t\t\t\telif version == 3:\n\t\t\t\t\theader_len = int.from_bytes(f.read(4), 'little')\n\t\t\t\t\tf.seek(12 + header_len)  # Skip to ZIP data","sourceCodeStart":1183,"sourceCodeEnd":1219,"githubUrl":"https://github.com/browser-use/browser-use/blob/6c73fced2f6d45a11d88622fe56365a5fe18f28b/browser_use/browser/profile.py#L1183-L1219","documentation":"_extract_extension unzipped the downloaded file successfully but found no manifest.json at the archive root — every real Chrome extension must ship one. Usually means the URL served an HTML error page or a ZIP whose manifest sits in a subdirectory rather than a direct .crx.","triggerScenarios":"extensions url points to a Chrome Web Store page or a redirect that returns HTML zipped/renamed; a GitHub release asset that is a source ZIP with the extension nested one folder deep; a corrupted download.","commonSituations":"Pasting the Web Store listing URL instead of the direct .crx download URL; GitHub 'Download ZIP' of a repo where manifest.json is inside <repo>-main/; truncated downloads.","solutions":["Inspect the downloaded artifact (unzip -l) — if you see HTML files or a nested folder, the URL is wrong.","Use the direct .crx asset URL (e.g. the GitHub release .crx file or a direct CDN link), not a page URL.","For nested ZIPs, download and extract manually, then point extensions at the directory containing manifest.json.","For repos, pack the extension yourself (zip manifest.json + sources) or reference a subdirectory path locally."],"exampleFix":"# before\nprofile = BrowserProfile(extensions=[{'url': 'https://github.com/foo/bar/archive/refs/heads/main.zip'}])  # manifest nested\n\n# after\n# download, unzip, then load the folder containing manifest.json:\nprofile = BrowserProfile(extensions=[{'path': '/opt/ext/bar-main/extension'}])","handlingStrategy":"validation","validationCode":"import zipfile\n\ndef zip_has_root_manifest(path: str) -> bool:\n    with zipfile.ZipFile(path) as z:\n        return 'manifest.json' in z.namelist()\n\n# verify the artifact before wiring it into BrowserProfile","typeGuard":null,"tryCatchPattern":"try:\n    profile = BrowserProfile(extensions=[{'url': ext_url}])\nexcept Exception as e:\n    if 'No manifest.json' in str(e):\n        # download + extract manually, locate manifest.json, use directory form\n        profile = BrowserProfile(extensions=[{'path': found_ext_dir}])\n    else:\n        raise","preventionTips":["Use direct .crx download URLs, never Web Store page URLs or repo source ZIPs.","Verify artifacts once in CI (unzip -l | grep manifest.json) and cache them.","For GitHub projects, reference the release .crx asset or ship an unpacked dir."],"tags":["extension","crx","manifest","download"],"backgroundTag":null,"analyzedSha":"6c73fced2f6d45a11d88622fe56365a5fe18f28b","analyzedAt":"2026-08-14T19:42:40.557Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}