golangci/golangci-lint · error

reading go.mod file: %w

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.

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)

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.