{"record":{"id":"2929ba8e5728b18a","repo":"google-gemini/gemini-cli","slug":"extension-not-found","errorCode":null,"errorMessage":"Extension not found","messagePattern":"Extension not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/config/extension-manager.ts","lineNumber":454,"sourceCode":"\n        const metadataString = JSON.stringify(installMetadata, null, 2);\n        const metadataPath = path.join(\n          destinationPath,\n          INSTALL_METADATA_FILENAME,\n        );\n        await fs.promises.writeFile(metadataPath, metadataString);\n\n        // Establish trust at point of installation\n        await this.storeExtensionIntegrity(\n          newExtensionConfig.name,\n          installMetadata,\n        );\n\n        // TODO: Gracefully handle this call failing, we should back up the old\n        // extension prior to overwriting it and then restore and restart it.\n        extension = await this.loadExtension(destinationPath);\n        if (!extension) {\n          throw new Error(`Extension not found`);\n        }\n        if (isUpdate) {\n          await logExtensionUpdateEvent(\n            this.telemetryConfig,\n            new ExtensionUpdateEvent(\n              newExtensionConfig.name,\n              hashValue(newExtensionConfig.name),\n              getExtensionId(newExtensionConfig, installMetadata),\n              newExtensionConfig.version,\n              previousExtensionConfig.version,\n              installMetadata.type,\n              CoreToolCallStatus.Success,\n            ),\n          );\n\n          if (newExtensionName !== previousName) {\n            if (wasEnabledGlobally) {\n              await this.enableExtension(newExtensionName, SettingScope.User);","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/cli/src/config/extension-manager.ts#L436-L472","documentation":"Thrown at the very end of install when `loadExtension(destinationPath)` returns null/undefined after the files have been copied and metadata written. `loadExtension` returns null when it cannot find or parse a valid extension manifest at the destination, meaning the source package was structured incorrectly or was incomplete.","triggerScenarios":"The source repository is missing the manifest file (`extension.json`/`gemini-extension.json`); the manifest exists but is invalid JSON; the manifest lacks required fields; only part of the extension was copied.","commonSituations":"Installing a repo that isn't actually a Gemini extension; pointing at a subpath that has the manifest but missing sibling files; a git clone that succeeded but the default branch lacks the manifest; an empty release asset.","solutions":["Open the source repo and confirm it has a valid extension manifest at its root (or at the `--path` subpath).","Validate the manifest JSON: `node -e \"JSON.parse(require('fs').readFileSync('extension.json'))\"`.","Ensure required manifest fields (`name`, `version`) are present.","Re-clone from a known-good revision and retry."],"exampleFix":"// before\n$ gemini extensions install owner/not-an-extension\n// after\n$ gemini extensions install owner/real-extension","handlingStrategy":"validation","validationCode":"const manifestPath = path.join(sourceDir, 'extension.json');\nif (!fs.existsSync(manifestPath)) {\n  throw new Error('Source has no extension manifest; cannot load.');\n}\nconst manifest = JSON.parse(await fs.promises.readFile(manifestPath, 'utf8'));\nif (!manifest.name || !manifest.version) {\n  throw new Error('Manifest missing required fields: name, version.');\n}","typeGuard":"function isExtensionManifest(v: unknown): v is { name: string; version: string } {\n  return typeof v === 'object' && v !== null &&\n    typeof (v as { name?: unknown }).name === 'string' &&\n    typeof (v as { version?: unknown }).version === 'string';\n}","tryCatchPattern":"try {\n  extension = await this.loadExtension(destinationPath);\n  if (!extension) throw new Error('Extension not found');\n} catch (e) {\n  await fs.promises.rm(destinationPath, { recursive: true, force: true }).catch(() => {});\n  throw e;\n}","preventionTips":["Validate the source repo has a Gemini extension manifest before installing.","Pin installs to a specific git tag known to ship a manifest.","Treat `loadExtension` returning null as a corrupt-package signal and clean up."],"tags":["extensions","manifest","load"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}