golang/go · error

git remote (%s) must not be local directory

Error message

git remote (%s) must not be local directory

What it means

Thrown by newGitRepo in remote mode when the remote string has no '://' scheme AND no ':' — it looks like a bare path, not a URL. Go requires a proper URL scheme for remote git repos; a bare path is treated as a potential local directory, which is disallowed in remote mode.

Source

Thrown at src/cmd/go/internal/modfetch/codehost/git.go:71

		}
		info, err := os.Stat(remote)
		if err != nil {
			return nil, err
		}
		if !info.IsDir() {
			return nil, fmt.Errorf("%s exists but is not a directory", remote)
		}
		r.dir = remote
		r.mu.Path = r.dir + ".lock"
		r.sha256Hashes = r.checkConfigSHA256(ctx)
		return r, nil
	}
	// This is a remote path lookup.
	if !strings.Contains(remote, "://") { // No URL scheme, could be host:path
		if strings.Contains(remote, ":") {
			return nil, fmt.Errorf("git remote (%s) must not be local directory (use URL syntax not host:path syntax)", remote)
		}
		return nil, fmt.Errorf("git remote (%s) must not be local directory", remote)
	}
	var err error
	r.dir, r.mu.Path, err = WorkDir(ctx, gitWorkDirType, r.remote)
	if err != nil {
		return nil, err
	}

	unlock, err := r.mu.Lock()
	if err != nil {
		return nil, err
	}
	defer unlock()

	if _, err := os.Stat(filepath.Join(r.dir, "objects")); err != nil {
		repoSha256Hash := false
		if refs, lrErr := r.loadRefs(ctx); lrErr == nil {
			// Check any ref's hash, it doesn't matter which; they won't be mixed
			// between sha1 and sha256 for the moment.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. If the source is local, use local mode (replace with a filesystem path, which go handles natively).
  2. If a remote URL is intended, add a scheme: 'file:///absolute/path' or 'https://host/repo.git'.
  3. Check the replace directive and ensure it uses the correct form (path for local, URL for remote).
  4. Run 'go mod edit -print' to inspect resolved paths.

Example fix

// before (go.mod) — bare path in a context expecting a remote
require example.com/mod v1.0.0 // resolves to bare path
// after — use a proper replace for local
replace example.com/mod => /home/user/projects/mod
Defensive patterns

Strategy: validation

Validate before calling

func validateRemoteURL(remote string) error {
    if !strings.Contains(remote, "://") {
        return fmt.Errorf("remote %q must be a URL with a scheme", remote)
    }
    return nil
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: A module source string that is a relative or absolute filesystem path passed where a URL is expected, without a scheme. Happens with malformed replace directives or custom VCS tooling calling codehost directly.

Common situations: Replace directive using './path/to/repo' without 'file://' prefix when a remote is required; a module path that resolves to a bare path via a proxy misconfiguration; importing a local path as if it were a remote module.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/fb99224dd8201921. Report an issue: GitHub.