google-gemini/gemini-cli · error · Error
Extension not found
Error message
Extension not found
What it means
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.
Source
Thrown at packages/cli/src/config/extension-manager.ts:454
const metadataString = JSON.stringify(installMetadata, null, 2);
const metadataPath = path.join(
destinationPath,
INSTALL_METADATA_FILENAME,
);
await fs.promises.writeFile(metadataPath, metadataString);
// Establish trust at point of installation
await this.storeExtensionIntegrity(
newExtensionConfig.name,
installMetadata,
);
// TODO: Gracefully handle this call failing, we should back up the old
// extension prior to overwriting it and then restore and restart it.
extension = await this.loadExtension(destinationPath);
if (!extension) {
throw new Error(`Extension not found`);
}
if (isUpdate) {
await logExtensionUpdateEvent(
this.telemetryConfig,
new ExtensionUpdateEvent(
newExtensionConfig.name,
hashValue(newExtensionConfig.name),
getExtensionId(newExtensionConfig, installMetadata),
newExtensionConfig.version,
previousExtensionConfig.version,
installMetadata.type,
CoreToolCallStatus.Success,
),
);
if (newExtensionName !== previousName) {
if (wasEnabledGlobally) {
await this.enableExtension(newExtensionName, SettingScope.User);View on GitHub (pinned to 5024443c72)
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.
Example fix
// before $ gemini extensions install owner/not-an-extension // after $ gemini extensions install owner/real-extension
Defensive patterns
Strategy: validation
Validate before calling
const manifestPath = path.join(sourceDir, 'extension.json');
if (!fs.existsSync(manifestPath)) {
throw new Error('Source has no extension manifest; cannot load.');
}
const manifest = JSON.parse(await fs.promises.readFile(manifestPath, 'utf8'));
if (!manifest.name || !manifest.version) {
throw new Error('Manifest missing required fields: name, version.');
} Type guard
function isExtensionManifest(v: unknown): v is { name: string; version: string } {
return typeof v === 'object' && v !== null &&
typeof (v as { name?: unknown }).name === 'string' &&
typeof (v as { version?: unknown }).version === 'string';
} Try / catch
try {
extension = await this.loadExtension(destinationPath);
if (!extension) throw new Error('Extension not found');
} catch (e) {
await fs.promises.rm(destinationPath, { recursive: true, force: true }).catch(() => {});
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid scope: ${argv.scope}. Please use one of ${Object.val
- Invalid scope: ${argv.scope}. Please use one of ${Object.val
- Installation aborted: Folder "${absolutePath}" is not truste
- The source argument must be provided.
- Path already exists: ${path}
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/2929ba8e5728b18a.
Report an issue: GitHub.