google-gemini/gemini-cli · error · Error
Cannot update to "${newExtensionName}" because an extension
Error message
Cannot update to "${newExtensionName}" because an extension with that name is already installed. What it means
Thrown on the update path when the new manifest's `name` differs from `previousName` but a different already-installed extension already uses that new name. Renaming into a colliding namespace is refused to avoid two extensions claiming the same identity.
Source
Thrown at packages/cli/src/config/extension-manager.ts:318
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 &&
previous.hooks &&
Object.keys(previous.hooks).length > 0
);
const newSkills = await loadSkillsFromDir(
path.join(localSourcePath, 'skills'),
);
const previousSkills = previous?.skills ?? [];View on GitHub (pinned to 5024443c72)
Solutions
- Uninstall the extension that currently owns the target name before updating.
- Keep the previous name to avoid the collision (do not rename the manifest).
- Use distinct names across forks so updates never collide.
Example fix
// before update extA v1 (name 'B') while extB exists // collision // after uninstall extB; then update extA
Defensive patterns
Strategy: validation
Validate before calling
const conflict = extensionManager
.getExtensions()
.find((e) => e.name === newExtensionName && e.name !== previousName);
if (isUpdate && conflict) {
throw new Error(`Target name ${newExtensionName} already in use.`);
} Type guard
function renameCollides(newName: string, prevName: string, installed: { name: string }[]): boolean {
return newName !== prevName && installed.some((e) => e.name === newName);
} Prevention
- Avoid renaming extensions across versions when a sibling already uses the target name.
- Uninstall the colliding sibling before the rename-update.
- Keep fork and upstream manifests under distinct names.
When it happens
Trigger: Updating extension A so that its new version is named `B`, when extension `B` is already installed; a fork and its upstream both named identically and you update the fork to match upstream's name.
Common situations: Two related extensions (fork + upstream) installed side by side; an upstream rename that lands while a fork is also installed; merging extension manifests.
Related errors
- Either an extension name or --all must be provided
- Extension "${previousName}" was not already installed, canno
- Extension "${newExtensionName}" is already installed. Please
- Cannot install extension "${newExtensionName}" because a dir
- Invalid scope: ${argv.scope}. Please use one of ${Object.val
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/1c40b49edf083d65.
Report an issue: GitHub.