jesseduffield/lazygit · error

unsupported or invalid remote URL: %s

Error message

unsupported or invalid remote URL: %s

What it means

replaceForkUsername in pkg/gui/controllers/remotes_controller.go rewrites the origin URL when creating a fork remote in-place. It supports three forms: the generic urlRegex (HTTPS, SSH-user@host:path, ssh:// URLs), and — only in integration tests — a relative ../user URL. Any other format falls through to 'unsupported or invalid remote URL'. Note ../user URLs are intentionally never valid in normal use.

Source

Thrown at pkg/gui/controllers/remotes_controller.go:241

// 1. SCP-like SSH: git@host:owner[/subgroups]/repo(.git)
// 2. SSH URL style: ssh://user@host[:port]/owner[/subgroups]/repo(.git)
// 3. HTTPS: https://host/owner[/subgroups]/repo(.git)
// 4. Only for integration tests: ../repo_name
var (
	urlRegex                = regexp.MustCompile(`^(git@[^:]+:|ssh://[^/]+/|https?://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$`)
	integrationTestUrlRegex = regexp.MustCompile(`^\.\./.+$`)
)

// Rewrites a Git remote URL to use the given fork username,
// keeping the repo name and host intact. Supports SCP-like SSH, SSH URL style, and HTTPS.
func replaceForkUsername(originUrl, forkUsername string, isIntegrationTest bool) (string, error) {
	if urlRegex.MatchString(originUrl) {
		return urlRegex.ReplaceAllString(originUrl, "${1}"+forkUsername+"/$3$4"), nil
	} else if isIntegrationTest && integrationTestUrlRegex.MatchString(originUrl) {
		return "../" + forkUsername, nil
	}

	return "", fmt.Errorf("unsupported or invalid remote URL: %s", originUrl)
}

func (self *RemotesController) getOrigin() *models.Remote {
	for _, remote := range self.c.Model().Remotes {
		if remote.Name == "origin" {
			return remote
		}
	}
	return nil
}

func (self *RemotesController) hasOriginRemote() func() *types.DisabledReason {
	return func() *types.DisabledReason {
		if self.getOrigin() == nil {
			return &types.DisabledReason{Text: self.c.Tr.NoOriginRemote}
		}

		return nil

View on GitHub (pinned to c477a2959b)

Solutions

  1. Re-add the remote with a supported URL form: https://host/owner/repo.git or git@host:owner/repo.git / ssh://git@host/owner/repo.git.
  2. Verify with `git remote -v` that the URL is well-formed (has a host and owner/repo path).
  3. If you cannot change the URL, create the fork remote manually (git remote add) instead of using lazygit's fork action.

Example fix

# terminal
# before
git remote set-url origin git://example.com/me/repo.git

# after
git remote set-url origin git@example.com:me/repo.git
Defensive patterns

Strategy: type-guard

Type guard

var supportedRemoteURL = regexp.MustCompile(`^(https?://|git@[^:]+:|ssh://)[^/]+/[^/]+/.+$`)

func isForkableURL(u string) bool {
	return supportedRemoteURL.MatchString(u)
}

Prevention

When it happens

Trigger: Pressing 'f' (fork) on a remote whose URL matches neither the supported HTTPS nor SSH patterns — e.g. a git:// URL, a local filesystem path like /srv/git/repo.git (not under test mode), or a malformed remote URL with no host.

Common situations: Repos cloned from local mirrors or bundled paths; exotic transports (git://, rsync://); remotes added by tooling with unconventional URL spellings; attempting fork on a self-hosted setup whose URL has an unusual scheme.

Related errors


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/22d7eed6c234b055. Report an issue: GitHub.