golang/go · warning

path %q matched multiple packages

Error message

path %q matched multiple packages

What it means

Returned by loadPackage after PackagesAndErrors returned a count other than 1 for a literal pattern. A literal path resolving to multiple packages is ambiguous — typically because build constraints or _test suffix produce more than one loadable package for the same directory.

Source

Thrown at src/cmd/go/internal/doc/doc.go:632

	// not fall through to internal-only matches for the same package path.
	nonInternal[len(nonInternal)-1].nextOffset = dirs.offset
	return append(nonInternal, internal...)
}

func loadPackage(ctx context.Context, loader *modload.Loader, pattern string) (*load.Package, error) {
	if !search.NewMatch(pattern).IsLiteral() {
		return nil, fmt.Errorf("pattern %q does not specify a single package", pattern)
	}

	pkgOpts := load.PackageOpts{
		IgnoreImports:      true,
		SuppressBuildInfo:  true,
		SuppressEmbedFiles: true,
	}
	pkgs := load.PackagesAndErrors(loader, ctx, pkgOpts, []string{pattern})

	if len(pkgs) != 1 {
		return nil, fmt.Errorf("path %q matched multiple packages", pattern)
	}

	p := pkgs[0]
	if p.Error != nil {
		return nil, p.Error
	}
	return p, nil
}

func mustLoadPackage(ctx context.Context, loader *modload.Loader, dir string) *load.Package {
	pkg, err := loadPackage(ctx, loader, dir)
	if err != nil {
		log.Fatal(err)
	}
	return pkg
}

// dotPaths lists all the dotted paths legal on Unix-like and

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Disambiguate with build tags or by selecting the specific package variant.
  2. Run `go list <pattern>` to see all matches and pick one.
  3. Reorganize the directory so one path == one package.
  4. Remove the _test ambiguity by aligning package names.

Example fix

# before
$ go doc ./splitpkg
# -> path "./splitpkg" matched multiple packages

# after: see the matches, then target one
$ go list ./splitpkg
$ go doc ./splitpkg  # after resolving the build-tag split
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("go", "list", pattern).Output()
if err == nil && len(bytes.Split(out, []byte("\n"))) > 1 {
    return fmt.Errorf("%q matches multiple packages; narrow it down", pattern)
}

Prevention

When it happens

Trigger: A directory that yields multiple packages under the active build tags (e.g. a package and its _test variant, or files split by build tags into two importable packages); passing a path that aliases two modules.

Common situations: Build-tag-separated packages in one dir; both foo and foo_test present; vendor + module path collision; ambiguous import after a module rename.

Related errors


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