google-gemini/gemini-cli · error · Error

Extension "${newExtensionName}" is already installed. Please

Error message

Extension "${newExtensionName}" is already installed. Please uninstall it first.

What it means

Thrown on the fresh-install path (`isUpdate` is false) when an extension with the same `newExtensionName` is already loaded. The manager refuses to overwrite an installed extension silently; the user must uninstall first.

Source

Thrown at packages/cli/src/config/extension-manager.ts:314

        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 &&
          previous.hooks &&
          Object.keys(previous.hooks).length > 0
        );

View on GitHub (pinned to 5024443c72)

Solutions

  1. Uninstall the existing extension first: `gemini extensions uninstall <name>`.
  2. If you want to switch sources, pass `previousExtensionConfig` so the call is treated as an update rather than a fresh install.
  3. Confirm the manifest `name` field is unique across installed extensions.

Example fix

// before
$ gemini extensions install owner/repo-fork  # name collides with installed
// after
$ gemini extensions uninstall my-ext && gemini extensions install owner/repo-fork
Defensive patterns

Strategy: validation

Validate before calling

const installed = extensionManager.getExtensions();
if (!isUpdate && installed.some((e) => e.name === newExtensionName)) {
  throw new Error(`${newExtensionName} already installed. Uninstall first.`);
}

Type guard

function nameIsFree(name: string, installed: { name: string }[]): boolean {
  return !installed.some((e) => e.name === name);
}

Prevention

When it happens

Trigger: Running `gemini extensions install owner/repo` for an extension whose manifest `name` collides with an already-installed one; reinstalling from a different source without uninstalling first.

Common situations: Installing the same extension from two different URLs/forks; a renamed source that ships the same `name` field in its manifest; reinstalling after a partial failure that left the prior install loaded.

Related errors


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