golang/go · error
invalid package name: %q
Error message
invalid package name: %q
What it means
Thrown by types2's resolver after a successful import when the returned package has an invalid name — either "_" (blank import-only) or "" (empty). The comment notes this can normally only happen through post-creation manipulation of package objects, since well-formed importers always set a real name. The package is set to nil so a synthetic fake package gets created and the BrokenImport is reported as 'could not import %s'.
Source
Thrown at src/cmd/compile/internal/types2/resolver.go:164
// ordinary import
var err error
if importer := check.conf.Importer; importer == nil {
err = fmt.Errorf("Config.Importer not installed")
} else if importerFrom, ok := importer.(ImporterFrom); ok {
imp, err = importerFrom.ImportFrom(path, dir, 0)
if imp == nil && err == nil {
err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir)
}
} else {
imp, err = importer.Import(path)
if imp == nil && err == nil {
err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path)
}
}
// make sure we have a valid package name
// (errors here can only happen through manipulation of packages after creation)
if err == nil && imp != nil && (imp.name == "_" || imp.name == "") {
err = fmt.Errorf("invalid package name: %q", imp.name)
imp = nil // create fake package below
}
if err != nil {
check.errorf(pos, BrokenImport, "could not import %s (%s)", path, err)
if imp == nil {
// create a new fake package
// come up with a sensible package name (heuristic)
name := strings.TrimSuffix(path, "/")
if i := strings.LastIndex(name, "/"); i >= 0 {
name = name[i+1:]
}
imp = NewPackage(path, name)
}
// continue to use the package as best as we can
imp.fake = true // avoid follow-up lookup failures
}
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure any custom importer sets a valid, non-blank package name (call NewPackage with a real name derived from the path)
- Audit code that constructs *types.Package objects and verify name is never "_" or empty
- If importing real packages, use importer.ForDefault / gcimporter rather than hand-building packages
Example fix
// before pkg := types.NewPackage(path, "_") // after name := path[strings.LastIndex(path, "/")+1:] pkg := types.NewPackage(path, name)
Defensive patterns
Strategy: validation
Validate before calling
// Before exposing a *types.Package from an importer, validate its name:
func validPkg(p *types.Package) error {
if p == nil { return fmt.Errorf("nil package") }
if p.Name() == "" || p.Name() == "_" {
return fmt.Errorf("invalid package name %q for %s", p.Name(), p.Path())
}
return nil
} Prevention
- Always pass a concrete non-blank name to types.NewPackage
- Derive the name from the path tail rather than hard-coding "_"
- Do not mutate pkg names after creation
When it happens
Trigger: Produced when imp is non-nil, err is nil, and imp.name is "_" or "". Reachable via a buggy importer that constructs packages via NewPackage with a blank/empty name, or via code that mutates a package's name field after creation.
Common situations: Custom importer that calls types.NewPackage(path, "") or types.NewPackage(path, "_"). A test harness or code-generation tool that fabricates package objects with placeholder names. Tampered/corrupted export data feeding an importer.
Related errors
- Config.Importer.Import(%s) returned nil but no error
- can't resolve import %s
- can't resolve export %s
- non-file URL
- file URL missing path
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/2879928ce1202f2e.
Report an issue: GitHub.