golang/go · error

invalid package directory

Error message

invalid package directory %q

What it means

The package directory path (p.Dir) contains a carriage return ('\r') or newline ('\n') character. These control characters would break command-line construction and build scripts that pass the directory as an argument, so the toolchain rejects them outright via strings.ContainsAny(p.Dir, "\r\n").

Solutions

  1. Rename the directory to remove any '\r' or '\n' characters.
  2. If the path was set via a build script or environment variable, sanitize it to strip control characters.
  3. Check for hidden characters: use 'ls -la', 'od -c', or 'xxd' on the directory path.
  4. Audit build scripts for unsanitized user input in path construction.
Defensive patterns

Strategy: validation

Validate before calling

// Validate that a directory path contains no control characters.
func validatePackageDir(dir string) error {
    if strings.ContainsAny(dir, "\r\n") {
        return fmt.Errorf("package directory %q contains control characters (CR or LF)", dir)
    }
    return nil
}

Type guard

// Check whether a path is safe for use as a package directory.
func isSafeDirPath(dir string) bool {
    return !strings.ContainsAny(dir, "\r\n")
}

Prevention

When it happens

Trigger: A filesystem path with embedded '\r' or '\n' in any directory component. This can occur through unusual directory creation, corrupted file listings, or paths constructed from untrusted or poorly-sanitized input that includes line terminators.

Common situations: Paths constructed programmatically from text processing that accidentally include newline characters. Directory names containing hidden control characters from copy-paste operations (especially from web pages or PDFs). Paths from external tools or build scripts that embed control characters. Shell injection artifacts.

Related errors


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

Appendix: source

Thrown at src/cmd/go/internal/load/pkg.go:2052

	// If first letter of input file is ASCII, it must be alphanumeric.
	// This avoids files turning into flags when invoking commands,
	// and other problems we haven't thought of yet.
	// Also, _cgo_ files must be generated by us, not supplied.
	// They are allowed to have //go:cgo_ldflag directives.
	// The directory scan ignores files beginning with _,
	// so we shouldn't see any _cgo_ files anyway, but just be safe.
	for _, file := range inputs {
		if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
			setError(fmt.Errorf("invalid input file name %q", file))
			return
		}
	}
	if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
		setError(fmt.Errorf("invalid input directory name %q", name))
		return
	}
	if strings.ContainsAny(p.Dir, "\r\n") {
		setError(fmt.Errorf("invalid package directory %q", p.Dir))
		return
	}

	// Build list of imported packages and full dependency list.
	imports := make([]*Package, 0, len(p.Imports))
	for i, path := range importPaths {
		if path == "C" {
			continue
		}
		p1, err := loadImport(ld, ctx, opts, nil, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport|allowInternalSimdImport)
		if err != nil && p.Error == nil {
			p.Error = err
			p.Incomplete = true
		}

		path = p1.ImportPath
		importPaths[i] = path
		if i < len(p.Imports) {

View on GitHub (pinned to b6b368adc5)