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

  1. Uninstall the extension that currently owns the target name before updating.
  2. Keep the previous name to avoid the collision (do not rename the manifest).
  3. 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

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


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/1c40b49edf083d65. Report an issue: GitHub.