usebruno/bruno · error · Error

Invalid Git URL

Error message

Invalid Git URL

What it means

Thrown by getRepoNameFromUrl (git/index.js:29). It delegates to the git-url-parse library to extract the repo name; if the input is empty, undefined, non-string, or otherwise unparseable, the library throws and the catch re-throws a plain 'Invalid Git URL'. Note that a sibling validator isGitRepositoryUrl exists but CloneGitRespository calls getRepoNameFromUrl without first running that check, and its Yup schema only enforces .required().

Source

Thrown at packages/bruno-app/src/utils/git/index.js:29

    // Validate that it has the essential parts of a git URL and uses valid protocols
    const validProtocols = ['git', 'ssh', 'http', 'https'];
    return !!(
      parsed
      && parsed.owner
      && parsed.source
      && validProtocols.includes(parsed.protocol)
    );
  } catch (error) {
    return false;
  }
};

export const getRepoNameFromUrl = (url) => {
  try {
    const parsedUrl = gitUrlParse(url);
    return parsedUrl.name;
  } catch (error) {
    throw new Error('Invalid Git URL');
  }
};

export const containsGitHubToken = (remoteUrl) => {
  const GITHUB_TOKEN_REGEX = /(ghp_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9_]{30,}/;
  return GITHUB_TOKEN_REGEX.test(remoteUrl);
};

export const getSafeGitRemoteUrls = (remotes = []) => {
  const remoteUrls = remotes
    ?.map((remote) => remote?.refs?.fetch)
    ?.filter((url) => typeof url === 'string' && url?.trim()?.length > 0);

  const safeRemoteUrls = remoteUrls
    ?.filter((remoteUrl) => !containsGitHubToken(remoteUrl));
  return safeRemoteUrls || [];
};

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Call isGitRepositoryUrl(url) before getRepoNameFromUrl(url) and reject early.
  2. Strengthen the Yup schema with a custom git-URL test (or .url()) so invalid input never reaches the parser.
  3. try/catch getRepoNameFromUrl at the call site (CloneGitRespository/index.js:133) and show a user-facing message.
  4. Trim and normalize the URL (add https:// if no scheme) before parsing.

Example fix

// before
const repoName = getRepoNameFromUrl(repositoryUrl);

// after
import { isGitRepositoryUrl, getRepoNameFromUrl } from 'utils/git';
if (!isGitRepositoryUrl(repositoryUrl)) {
  toast.error('Enter a valid Git URL (https://, git@, ssh://)');
  return;
}
const repoName = getRepoNameFromUrl(repositoryUrl);
Defensive patterns

Strategy: type-guard

Validate before calling

import { isGitRepositoryUrl } from 'utils/git';

if (!isGitRepositoryUrl(repositoryUrl)) {
  toast.error('Enter a valid Git URL (https://, git@, ssh://)');
  return;
}

Type guard

import { isGitRepositoryUrl } from 'utils/git';

const isValidGitUrl = (url) =>
  typeof url === 'string' && url.trim().length > 0 && isGitRepositoryUrl(url);

Try / catch

try {
  const repoName = getRepoNameFromUrl(repositoryUrl);
} catch (e) {
  toast.error('Enter a valid Git URL (https://, git@, ssh://)');
  return;
}

Prevention

When it happens

Trigger: Passing an empty string, undefined, a bare word with no protocol/owner, or a malformed URL to getRepoNameFromUrl. The clone dialog's Yup validation passes any non-empty string, so a typo like 'myrepo' or 'htp://x' reaches the parser and throws.

Common situations: User pastes a partial/typo'd clone URL; URL missing scheme (git@host:owner/repo vs https://...); trailing whitespace or stray characters; form submitted with a non-URL value.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/05314f1f26b05b74. Report an issue: GitHub.