golang/go · error

repository rooted at %s cannot contain module %s

Error message

repository rooted at %s cannot contain module %s

What it means

newCodeRepo computes codeDir (subdirectory of the repo for the module root). When codeRoot != path it requires pathPrefix to start with codeRoot; otherwise the repository root cannot logically contain the module. The %s pair is codeRoot and the module path. Distinct from 977: here the path/codeRoot prefix check passed but pathPrefix (path minus version suffix) is not under codeRoot.

Source

Thrown at src/cmd/go/internal/modfetch/coderepo.go:126

	//	codeRoot = gopkg.in/yaml.v2
	//	pathPrefix = gopkg.in/yaml
	//	pathMajor = .v2
	//	pseudoMajor = v2
	//
	// Starting in 1.25, subdir may be passed in by the go-import meta tag.
	// So it may be the case that:
	//	path = github.com/rsc/foo/v2
	//	codeRoot = github.com/rsc/foo
	//	subdir = bar/subdir
	//	pathPrefix = github.com/rsc/foo
	//	pathMajor = /v2
	//	pseudoMajor = v2
	// which means that codeDir = bar/subdir

	codeDir := ""
	if codeRoot != path {
		if !hasPathPrefix(pathPrefix, codeRoot) {
			return nil, fmt.Errorf("repository rooted at %s cannot contain module %s", codeRoot, path)
		}
		codeDir = strings.Trim(pathPrefix[len(codeRoot):], "/")
	}
	if subdir != "" {
		codeDir = filepath.ToSlash(filepath.Join(codeDir, subdir))
	}

	r := &codeRepo{
		modPath:     path,
		code:        code,
		codeRoot:    codeRoot,
		codeDir:     codeDir,
		pathPrefix:  pathPrefix,
		pathMajor:   pathMajor,
		pseudoMajor: pseudoMajor,
	}

	return r, nil

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Verify the module path, codeRoot, and (if present) subdir are mutually consistent — the path's non-version prefix must lie under codeRoot.
  2. Correct the go-import meta tag so the repository root actually contains the module directory.
  3. For multi-major repos, ensure each /vN path maps to a codeRoot that is a prefix of the path's prefix component.
  4. Fall back to GOPROXY to fetch a pre-built zip and avoid the vanity resolution.
Defensive patterns

Strategy: validation

Validate before calling

func codeRootContainsPrefix(codeRoot, path string) bool {
    prefix, _, ok := module.SplitPathVersion(path)
    if !ok { return false }
    return hasPathPrefix(prefix, codeRoot)
}

Prevention

When it happens

Trigger: path passes the initial hasPathPrefix(path, codeRoot) check, but after SplitPathVersion the resulting pathPrefix is not under codeRoot. Happens with malformed gopkg.in paths or when a meta tag's subdir interaction produces an inconsistent prefix.

Common situations: A vanity import where the path's version suffix splits the path in a way that leaves pathPrefix outside codeRoot; mixed major-version paths in one repo with an incorrect codeRoot; meta-tag subdir (Go 1.25+) misconfigured so the joined codeDir escapes the repo.

Related errors


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