google-gemini/gemini-cli · error · Error
Extension "${previousName}" was not already installed, canno
Error message
Extension "${previousName}" was not already installed, cannot update it. What it means
Thrown on the update path (`previousExtensionConfig` was supplied, so `isUpdate` is true) when no currently-loaded extension matches `previousName`. The update logic needs the previous extension's hooks/skills/enablement state to migrate cleanly, so a missing previous extension is fatal.
Source
Thrown at packages/cli/src/config/extension-manager.ts:310
throw new Error(`Unsupported install type: ${installMetadata.type}`);
}
try {
newExtensionConfig = await this.loadExtensionConfig(localSourcePath);
const newExtensionName = newExtensionConfig.name;
const previousName = previousExtensionConfig?.name ?? newExtensionName;
const previous = this.getExtensions().find(
(installed) => installed.name === previousName,
);
const nameConflict = this.getExtensions().find(
(installed) =>
installed.name === newExtensionName &&
installed.name !== previousName,
);
if (isUpdate && !previous) {
throw new Error(
`Extension "${previousName}" was not already installed, cannot update it.`,
);
} else if (!isUpdate && previous) {
throw new Error(
`Extension "${newExtensionName}" is already installed. Please uninstall it first.`,
);
} else if (isUpdate && nameConflict) {
throw new Error(
`Cannot update to "${newExtensionName}" because an extension with that name is already installed.`,
);
}
const newHasHooks = fs.existsSync(
path.join(localSourcePath, 'hooks', 'hooks.json'),
);
const previousHasHooks = !!(
isUpdate &&
previous &&View on GitHub (pinned to 5024443c72)
Solutions
- Uninstall the dangling config entry first, then install fresh instead of updating.
- Reinstall the previous version so the extension is loadable, then retry the update.
- Inspect `~/.gemini/extensions/` and remove stale entries before retrying.
Example fix
// before installOrUpdateExtension(meta, previousConfig) // previous no longer on disk // after await uninstallExtension(previousName); await installOrUpdateExtension(meta)
Defensive patterns
Strategy: validation
Validate before calling
const previous = extensionManager.getExtensions().find((e) => e.name === previousName);
if (isUpdate && !previous) {
throw new Error(`Cannot update ${previousName}: not installed.`);
} Type guard
function isInstalled(name: string, installed: { name: string }[]): boolean {
return installed.some((e) => e.name === name);
} Prevention
- Before calling update, confirm the previous extension loads via `getExtensions()`.
- If a directory was deleted manually, run uninstall first to clean the config.
- Don't rely on stale `previousExtensionConfig` after a manual cleanup.
When it happens
Trigger: The previous extension's directory was manually deleted from disk while its config entry persisted; `loadExtensions` skipped it due to a load error; the extension was renamed on disk but the config still references the old name.
Common situations: Manual `rm -rf` of an extension directory; a failed uninstall that left config behind; switching machines with a partial sync; corrupted extension state.
Related errors
- Either an extension name or --all must be provided
- Cannot update to "${newExtensionName}" because an extension
- 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
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/534f5de6cdda337b.
Report an issue: GitHub.