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

  1. Ensure any custom importer sets a valid, non-blank package name (call NewPackage with a real name derived from the path)
  2. Audit code that constructs *types.Package objects and verify name is never "_" or empty
  3. 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

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


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