google-gemini/gemini-cli · error · Error

Failed to install extension ${installMetadata.source}: ${res

Error message

Failed to install extension ${installMetadata.source}: ${result.errorMessage}

What it means

Thrown when downloading a github-release artifact fails AND the user declines (or is not asked for) the git-clone fallback. The wrapped message includes `result.errorMessage` from the download attempt (e.g. network error, 404, missing release). The error closes the install attempt without a fallback.

Source

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

          if (result.success) {
            installMetadata.type = result.type;
            installMetadata.releaseTag = result.tagName;
          } else if (
            // This repo has no github releases, and wasn't explicitly installed
            // from a github release, unconditionally just clone it.
            (result.failureReason === 'no release data' &&
              installMetadata.type === 'git') ||
            // Otherwise ask the user if they would like to try a git clone.
            (await (requestConsentOverride ?? this.requestConsent)(
              `Error downloading github release for ${installMetadata.source} with the following error: ${result.errorMessage}.

Would you like to attempt to install via "git clone" instead?`,
            ))
          ) {
            await cloneFromGit(installMetadata, tempDir);
            installMetadata.type = 'git';
          } else {
            throw new Error(
              `Failed to install extension ${installMetadata.source}: ${result.errorMessage}`,
            );
          }
        }
        localSourcePath = tempDir;
      } else if (
        installMetadata.type === 'local' ||
        installMetadata.type === 'link'
      ) {
        localSourcePath = getRealPath(installMetadata.source);
      } else {
        throw new Error(`Unsupported install type: ${installMetadata.type}`);
      }

      try {
        newExtensionConfig = await this.loadExtensionConfig(localSourcePath);

        const newExtensionName = newExtensionConfig.name;

View on GitHub (pinned to 5024443c72)

Solutions

  1. Re-run with `--include-directories` / network access to GitHub and retry.
  2. Set `GH_TOKEN` / `GITHUB_TOKEN` to authenticate and raise rate limits.
  3. Accept the git-clone fallback at the prompt if the release simply has no assets.
  4. Install directly from a git URL so `tryParseGithubUrl` is bypassed and `cloneFromGit` is used from the start.

Example fix

// before
$ gemini extensions install owner/repo@v1.0  # release download fails, decline clone
// after
$ GH_TOKEN=*** gemini extensions install owner/repo@v1.0  # accept clone fallback
Defensive patterns

Strategy: retry

Validate before calling

function canReachGitHub(): Promise<boolean> {
  return fetch('https://api.github.com', { method: 'HEAD' })
    .then((r) => r.ok || r.status === 403)
    .catch(() => false);
}

Type guard

function isGithubRateLimited(msg: string): boolean {
  return /rate limit/i.test(msg);
}

Try / catch

try {
  await installOrUpdateExtension(meta);
} catch (e) {
  if (/Failed to install extension/.test(getErrorMessage(e))) {
    // retry with git clone path explicitly, or back off and retry after rate-limit reset
    meta.type = 'git';
    await installOrUpdateExtension(meta);
  } else throw e;
}

Prevention

When it happens

Trigger: The release download returns `success: false` for a reason other than `no release data` (e.g. rate limit, network failure, missing asset), and the consent prompt for git-clone fallback is declined; or `requestConsentOverride` returns false in a non-interactive run.

Common situations: GitHub API rate limits on unauthenticated installs; typos in the release tag; private repos without credentials; CI runners with no network egress to objects.githubusercontent.com; misconfigured proxies.

Related errors


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