google-gemini/gemini-cli · error · TypeError

Invalid repo URL: ${source}

Error message

Invalid repo URL: ${source}

What it means

Thrown as a TypeError by tryParseGithubUrl() when new URL(source, 'https://github.com') throws — i.e., the source is so malformed it cannot be parsed even relative to the github base. The comment notes TypeError is used deliberately to keep a consistent error contract for consumers expecting invalid-URL failures.

Source

Thrown at packages/cli/src/config/extensions/github.ts:106

  // Handle SCP-style SSH URLs.
  if (source.startsWith('git@')) {
    if (source.startsWith('git@github.com:')) {
      // It's a GitHub SSH URL, so normalize it for the URL parser.
      source = source.replace('git@github.com:', '');
    } else {
      // It's another provider's SSH URL (e.g., gitlab), so not a GitHub repo.
      return null;
    }
  }
  // Default to a github repo path, so `source` can be just an org/repo
  let parsedUrl: URL;
  try {
    // Use the standard URL constructor for backward compatibility.
    parsedUrl = new URL(source, 'https://github.com');
  } catch (e) {
    // Throw a TypeError to maintain a consistent error contract for invalid URLs.
    // This avoids a breaking change for consumers who might expect a TypeError.
    throw new TypeError(`Invalid repo URL: ${source}`, { cause: e });
  }

  if (!parsedUrl) {
    throw new Error(`Invalid repo URL: ${source}`);
  }
  if (parsedUrl?.host !== 'github.com') {
    return null;
  }
  // The pathname should be "/owner/repo".
  const parts = parsedUrl?.pathname
    .split('/')
    // Remove the empty segments, fixes trailing and leading slashes
    .filter((part) => part !== '');

  if (parts?.length !== 2) {
    throw new Error(
      `Invalid GitHub repository source: ${source}. Expected "owner/repo" or a github repo uri.`,
    );

View on GitHub (pinned to 5024443c72)

Solutions

  1. Trim and validate the source string before calling tryParseGithubUrl.
  2. Pass a well-formed 'owner/repo' shorthand or a full https/github URL.
  3. Catch TypeError specifically if you iterate over candidate sources.

Example fix

// before
const info = tryParseGithubUrl(rawSource);
// after
const trimmed = rawSource.trim();
if (!/^[^\s]+$/.test(trimmed)) throw new Error('source must not contain whitespace');
const info = tryParseGithubUrl(trimmed);
Defensive patterns

Strategy: validation

Validate before calling

function isValidSourceToken(source: string): boolean {
  const s = source.trim();
  return s.length > 0 && !/\s/.test(s);
}

Type guard

function isParsableUrl(source: string, base = 'https://github.com'): boolean { try { new URL(source, base); return true; } catch { return false; } }

Try / catch

try { tryParseGithubUrl(src); } catch (e) { if (e instanceof TypeError) { /* skip invalid candidate */ } else throw e; }

Prevention

When it happens

Trigger: Calling tryParseGithubUrl with a source containing characters illegal in a URL (e.g., spaces, backslashes, certain control chars), or a scheme/structure the URL constructor rejects even with a base.

Common situations: User-typed source with a stray space or quote; copy-paste that includes surrounding markdown; a source read from a config file with trailing whitespace or BOM.

Related errors


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