golang/go · error

mixing of meta and non-meta packages is not allowed

Error message

mixing of meta and non-meta packages is not allowed

What it means

Thrown by libname() in cmd/go/internal/work during -buildmode=shared (building a shared library from a set of packages). It fires when the package arguments contain both a meta-package wildcard ("all", "std", "cmd", or "..."-style patterns recognized by search.IsMetaPackage) and an explicit non-meta package or import path. The shared-library name is derived from the package set, and mixing the two forms is structurally ambiguous, so the go command rejects it.

Source

Thrown at src/cmd/go/internal/work/build.go:685

	if len(libname) == 0 { // non-meta packages only. use import paths
		if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
			// Special case of "foo/..." as mentioned above.
			arg := strings.TrimSuffix(args[0], "/...")
			if build.IsLocalImport(arg) {
				cwd, _ := os.Getwd()
				bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
				if bp.ImportPath != "" && bp.ImportPath != "." {
					arg = bp.ImportPath
				}
			}
			appendName(strings.ReplaceAll(arg, "/", "-"))
		} else {
			for _, pkg := range pkgs {
				appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
			}
		}
	} else if haveNonMeta { // have both meta package and a non-meta one
		return "", errors.New("mixing of meta and non-meta packages is not allowed")
	}
	// TODO(mwhudson): Needs to change for platforms that use different naming
	// conventions...
	return "lib" + libname + ".so", nil
}

func runInstall(ctx context.Context, cmd *base.Command, args []string) {
	moduleLoader := modload.NewLoader()
	for _, arg := range args {
		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
			installOutsideModule(moduleLoader, ctx, args)
			return
		}
	}

	moduleLoader.InitWorkfile()
	BuildInit(moduleLoader)
	pkgs := load.PackagesAndErrors(moduleLoader, ctx, load.PackageOpts{AutoVCS: true}, args)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Split into two separate -buildmode=shared invocations: one for the meta-package set, one for the explicit packages.
  2. Replace the meta-package with its explicit expansion (e.g. list packages under std with `go list std` and pass those import paths together with your own).
  3. Drop the wildcard and pass only the concrete import paths you actually want in the shared library.
  4. Reconsider -buildmode=shared — it is niche; -buildmode=plugin or a regular archive may fit the goal better.

Example fix

# before
GOFLAGS=-buildmode=shared
go install -buildmode=shared std example.com/mylib
# after
go install -buildmode=shared std
go install -buildmode=shared example.com/mylib
Defensive patterns

Strategy: validation

Validate before calling

func validateSharedArgs(args []string) error {
    hasMeta, hasNonMeta := false, false
    for _, a := range args {
        if search.IsMetaPackage(a) { hasMeta = true } else { hasNonMeta = true }
    }
    if hasMeta && hasNonMeta {
        return errors.New("do not mix meta-package patterns with explicit import paths under -buildmode=shared")
    }
    return nil
}

Type guard

func argsAreHomogeneous(args []string) bool {
    saw := 0
    for _, a := range args {
        cur := 1
        if search.IsMetaPackage(a) { cur = 2 }
        if saw == 0 { saw = cur } else if saw != cur { return false }
    }
    return true
}

Prevention

When it happens

Trigger: Running `go install -buildmode=shared std example.com/lib` or `go build -buildmode=shared all ./mymod`. Any -buildmode=shared invocation whose args list contains at least one of all/std/cmd/... and at least one concrete import path or directory.

Common situations: Trying to bundle the standard library together with a project library into one .so. CI scripts that prepend "std" to a package list to share stdlib. Misuse of wildcard patterns combined with explicit deps.

Related errors


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