golang/go · error
%s exists but is not a directory
Error message
%s exists but is not a directory
What it means
Thrown by newGitRepo in local mode when os.Stat(remote) succeeds (the path exists) but info.IsDir() is false — the 'remote' is a regular file, not a git checkout directory. A local git repository must be a directory.
Source
Thrown at src/cmd/go/internal/modfetch/codehost/git.go:59
}
func (e notExistError) Error() string { return e.err.Error() }
func (notExistError) Is(err error) bool { return err == fs.ErrNotExist }
const gitWorkDirType = "git3"
func newGitRepo(ctx context.Context, remote string, local bool) (Repo, error) {
r := &gitRepo{remote: remote, local: local}
if local {
if strings.Contains(remote, "://") { // Local flag, but URL provided
return nil, fmt.Errorf("git remote (%s) lookup disabled", remote)
}
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
}View on GitHub (pinned to b6b368adc5)
Solutions
- Verify the path: 'ls -la <remote>' and confirm it is a directory.
- Update the replace directive or path to point at the actual git working directory.
- If you meant a remote URL, use URL syntax instead of a local path.
- Extract the archive if the source was downloaded as a tarball.
Example fix
# before (go.mod) replace example.com/mod => ./mod.tar.gz # after mkdir -p ./mod && tar -xzf mod.tar.gz -C ./mod replace example.com/mod => ./mod
Defensive patterns
Strategy: validation
Validate before calling
func validateLocalRepoPath(path string) error {
fi, err := os.Stat(path)
if err != nil { return err }
if !fi.IsDir() {
return fmt.Errorf("%q exists but is not a directory", path)
}
return nil
} Type guard
null
Try / catch
null
Prevention
- Point replace directives at directories, never at archives.
- In setup scripts, os.Stat replace targets and assert IsDir.
- Use 'go mod edit -replace' to set correct paths.
When it happens
Trigger: newGitRepo(ctx, remote, local=true) where remote is a path to a file (e.g. a tarball, a .git pack file, or any non-directory) rather than a working tree or bare repo directory.
Common situations: A replace directive pointing at a file instead of a directory; a path that was a directory but got replaced by an archive; a typo in the path resolving to a nearby file.
Related errors
- git remote (%s) lookup disabled
- git remote (%s) must not be local directory
- revision does not exist locally: %s
- git remote (%s) must not be local directory (use URL syntax
- %s exists but is not a directory
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a261361285bcdcaa.
Report an issue: GitHub.