golangci/golangci-lint · error

reading go.mod file

Error message

reading go.mod file: %w

What it means

parseGoMod reads the go.mod file from disk to detect the Go version; if os.ReadFile fails it wraps the OS error with this message. This happens when go.mod is missing, unreadable, or the resolved path is wrong.

Solutions

  1. Ensure go.mod exists at the expected location (repository/module root)
  2. Run golangci-lint from the module directory or fix the config directory/path settings
  3. Fix file permissions so the linting user can read go.mod
  4. Set the Go version explicitly in config (run.go) instead of relying on go.mod detection

Example fix

// before
detectGoVersionFromGoMod(ctx) // fails: no go.mod in cwd
// after
// run from module root, or ensure go.mod exists:
// $ cd /path/to/module && golangci-lint run
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat("go.mod"); err != nil {
	return fmt.Errorf("go.mod missing in %s: %w", dir, err)
}

Try / catch

if _, err := detectGoVersionFromGoMod(ctx); err != nil {
	var pe *fs.PathError
	if errors.As(err, &pe) { log.Printf("go.mod unreadable: %s", pe.Path) }
}

Prevention

When it happens

Trigger: Calling detectGoVersionFromGoMod with a path to a go.mod that does not exist, has restrictive permissions, or whose directory was deleted; bad cfgDir/working directory resolution pointing at the wrong path.

Common situations: Running golangci-lint in a module subdirectory without go.mod at the resolved path; CI checking out only partial repo; go.mod deleted or renamed; permission issues in containers.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/2b7dcae5dcd18165. Report an issue: GitHub.

Appendix: source

Thrown at pkg/config/config.go:168

func parseGoVersion(v string) string {
	raw := strings.TrimPrefix(v, "go")

	// prerelease version (ex: go1.24rc1)
	idx := strings.IndexFunc(raw, func(r rune) bool {
		return (r < '0' || r > '9') && r != '.'
	})

	if idx != -1 {
		raw = raw[:idx]
	}

	return raw
}

func parseGoMod(goMod string) (*modfile.File, error) {
	raw, err := os.ReadFile(filepath.Clean(goMod))
	if err != nil {
		return nil, fmt.Errorf("reading go.mod file: %w", err)
	}

	return modfile.Parse("go.mod", raw, nil)
}

func detectGoModFallback(ctx context.Context) string {
	info, err := gomod.GetModuleInfo(ctx)
	if err != nil {
		return ""
	}

	wd, err := os.Getwd()
	if err != nil {
		return ""
	}

	slices.SortFunc(info, func(a, b gomod.ModInfo) int {
		return cmp.Compare(len(b.Path), len(a.Path))

View on GitHub (pinned to ed7a235d2d)