google-gemini/gemini-cli · error · Error

Invalid extension name

Error message

Invalid extension name: "${name}". Only letters (a-z, A-Z), numbers (0-9), and dashes (-) are allowed.

What it means

The extension manager validates extension names with the regex /^[a-zA-Z0-9-]+$/ in validateName before performing install/lookup operations. Any name containing characters outside letters, digits, and dashes (spaces, underscores, dots, slashes, unicode) is rejected. This keeps names safe to embed in file paths, registry URLs, and CLI flags.

Solutions

  1. Sanitize the name to only [a-zA-Z0-9-], replacing invalid characters with dashes, before invoking the install command.
  2. If installing from a URL or subdirectory, extract just the base name (e.g. 'my-extension' from 'https://github.com/user/my-extension.git').
  3. Fix the extension's metadata/config file so its name field matches the allowed pattern.

Example fix

// before
gemini extensions install https://github.com/user/my_ext.git
// after
gemini extensions install my-ext
Defensive patterns

Strategy: validation

Validate before calling

if (!/^[a-zA-Z0-9-]+$/.test(name)) {
  throw new Error(`Invalid extension name: ${name}`);
}

Prevention

When it happens

Trigger: Calling inferInstallMetadata (or any extension install/lookup path) with a name argument that fails validateName's regex, e.g. a git URL, a scoped npm-style name like '@scope/pkg', or a name with '_' or '.'.

Common situations: Users pass a GitHub repo URL instead of the plain repo name, use underscores instead of dashes ('my_ext'), or a config file / registry entry contains a malformed extension name.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@6a466a7e2f (2026-09-16). Data as JSON: /api/errors/329375fc78f0e9af. Report an issue: GitHub.

Appendix: source

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

      if (!validation.isValid) {
        debugLogger.warn(
          `[ExtensionManager] Invalid contextFileName: "${contextFileName}" in extension "${config.name}". ${validation.errorMessage}`,
        );
        return null;
      }

      return validation.resolvedPath!;
    })
    .filter(
      (contextFilePath): contextFilePath is string =>
        contextFilePath !== null && fs.existsSync(contextFilePath),
    );
}

function validateName(name: string) {
  if (!/^[a-zA-Z0-9-]+$/.test(name)) {
    throw new Error(
      `Invalid extension name: "${name}". Only letters (a-z, A-Z), numbers (0-9), and dashes (-) are allowed.`,
    );
  }
}

export async function inferInstallMetadata(
  source: string,
  args: {
    ref?: string;
    autoUpdate?: boolean;
    allowPreRelease?: boolean;
  } = {},
): Promise<ExtensionInstallMetadata> {
  if (
    source.startsWith('http://') ||
    source.startsWith('https://') ||
    source.startsWith('git@') ||
    source.startsWith('sso://') ||

View on GitHub (pinned to 6a466a7e2f)