golang/go · error

directory %q is outside source root %q

Error message

directory %q is outside source root %q

What it means

In GOPATH mode (GO111MODULE=off), FromDir walks up from the package directory to locate a VCS root. As a precondition it verifies the directory is a strict subdirectory of the configured source root (GOPATH/src). If the directory equals or is not properly contained within srcRoot, it is rejected.

Source

Thrown at src/cmd/go/internal/vcs/vcs.go:494

	repo           string                              // repository to use (expand with match of re)
	vcs            string                              // version control system to use (expand with match of re)
	check          func(match map[string]string) error // additional checks
	schemelessRepo bool                                // if true, the repo pattern lacks a scheme
}

var allowmultiplevcs = godebug.New("allowmultiplevcs")

// FromDir inspects dir and its parents to determine the
// version control system and code repository to use.
// If no repository is found, FromDir returns an error
// equivalent to os.ErrNotExist.
func FromDir(dir, srcRoot string) (repoDir string, vcsCmd *Cmd, err error) {
	// Clean and double-check that dir is in (a subdirectory of) srcRoot.
	dir = filepath.Clean(dir)
	if srcRoot != "" {
		srcRoot = filepath.Clean(srcRoot)
		if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
			return "", nil, fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
		}
	}

	origDir := dir
	for len(dir) > len(srcRoot) {
		for _, vcs := range vcsList {
			if isVCSRootDir(dir, vcs.Roots) {
				if vcsCmd == nil {
					// Record first VCS we find.
					vcsCmd = vcs
					repoDir = dir
					if allowmultiplevcs.Value() == "1" {
						allowmultiplevcs.IncNonDefault()
						return repoDir, vcsCmd, nil
					}
					// If allowmultiplevcs is not set, keep looking for
					// repositories in current and parent directories and report
					// an error if one is found to mitigate VCS injection

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure GOPATH is set correctly: `go env GOPATH`
  2. Place your package under $GOPATH/src/<import-path>/
  3. Switch to module mode: run `go mod init` in your project and remove GO111MODULE=off
  4. Verify the directory is a genuine subdirectory of GOPATH/src (not a sibling or parent)

Example fix

# before: package outside GOPATH/src in GOPATH mode
export GO111MODULE=off
go build /tmp/myproject  # fails

# after: use module mode instead
go mod init example.com/myproject  # in the project dir
go build ./...
Defensive patterns

Strategy: validation

Validate before calling

# In GOPATH mode, verify the package dir is inside GOPATH/src
SRCROOT="$(go env GOPATH)/src"
PKGDIR="$(pwd)"
case "$PKGDIR/" in
  "$SRCROOT"/*) echo 'OK: inside GOPATH/src' ;;
  *) echo "ERROR: $PKGDIR is outside GOPATH/src ($SRCROOT)" ;;
esac

Try / catch

# Detect and guide: suggest module mode
go build ./... 2>&1 | grep -q 'outside source root' && {
  echo 'Switch to module mode: run go mod init in your project'
  exit 1
}

Prevention

When it happens

Trigger: GOPATH mode build/test where the package directory resolves to a path that is not inside GOPATH/src — the check `len(dir) <= len(srcRoot) || dir[len(srcRoot)] != Separator` fails.

Common situations: GOPATH not set or set incorrectly; package directory outside GOPATH/src; using a relative path that resolves outside GOPATH; symlink escaping the source root.

Related errors


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