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().

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.

Appendix: 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)