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
- Split into two separate -buildmode=shared invocations: one for the meta-package set, one for the explicit packages.
- 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).
- Drop the wildcard and pass only the concrete import paths you actually want in the shared library.
- 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
- Under -buildmode=shared, pass either all-meta or all-explicit args — never both.
- Replace meta-packages with `go list` output when you need fine control.
- Consider whether -buildmode=shared is really needed; it is rarely the right choice.
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
- non-file URL
- file URL missing path
- file URL encodes volume in host field: too few slashes?
- file URL missing drive letter
- value is neither 'auto' nor a valid bool
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/731dbe8536bc3adc.
Report an issue: GitHub.