golangci/golangci-lint · error

file %s not found: %w

Error message

file %s not found: %w

What it means

LoadConfiguration first calls findConfigurationFile to locate a config file in the current directory; if that returns an error, this wrapper reports 'file %s not found', embedding the (possibly empty) candidate path. It means no supported configuration file (e.g. YAML variants) could be found in the working directory.

Source

Thrown at pkg/commands/internal/configuration.go:98

	// Module name.
	Module string `yaml:"module"`

	// Import to use.
	Import string `yaml:"import,omitempty"`

	// Version of the module.
	// Only for module available through a Go proxy.
	Version string `yaml:"version,omitempty"`

	// Path to the local module.
	// Only for local module.
	Path string `yaml:"path,omitempty"`
}

func LoadConfiguration() (*Configuration, error) {
	configFilePath, err := findConfigurationFile()
	if err != nil {
		return nil, fmt.Errorf("file %s not found: %w", configFilePath, err)
	}

	file, err := os.Open(configFilePath)
	if err != nil {
		return nil, fmt.Errorf("file %s open: %w", configFilePath, err)
	}

	defer func() { _ = file.Close() }()

	var cfg Configuration

	err = yaml.NewDecoder(file).Decode(&cfg)
	if err != nil {
		return nil, fmt.Errorf("YAML decoding: %w", err)
	}

	return &cfg, nil
}

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. cd to the project root (or the directory containing the config) before running the command
  2. Create a configuration file with a supported extension/name in the current directory (e.g. config.yaml)
  3. Rename the existing config to a supported filename/extension the finder recognizes
  4. If the path in the message is empty, look at the wrapped error — the real failure is likely 'read directory' from findConfigurationFile, not a missing file

Example fix

// before
$ cd /tmp && tool build   # no config here
// after
$ cd ~/projects/myapp && tool build   # directory containing config.yaml
Defensive patterns

Strategy: validation

Validate before calling

supported := []string{".yaml", ".yml", ".json"}
entries, err := os.ReadDir(".")
if err != nil { return err }
found := false
for _, e := range entries {
    if slices.Contains(supported, strings.ToLower(filepath.Ext(e.Name()))) { found = true; break }
}
if !found {
    return fmt.Errorf("no config file with extensions %v in %s; run from the project root or create one", supported, ".")
}

Try / catch

cfg, err := LoadConfiguration()
if err != nil {
    var e *fs.PathError
    if strings.Contains(err.Error(), "not found") {
        log.Fatalf("no configuration file found in %s — cd to the project root or create config.yaml", mustGetwd())
    }
    return err
}

Prevention

When it happens

Trigger: preRunE invoked LoadConfiguration while os.ReadDir(".") found no file whose extension matches a supported configuration format, or findConfigurationFile returned an error that is not a lookup failure — note the message would then be misleading since configFilePath is empty on error.

Common situations: Running the CLI in a directory without the config file instead of the project root, config file renamed to an unsupported extension (e.g. .conf, .yml.gz), file hidden as .tool.yaml when only *.yaml is scanned, or running from a different CWD in CI.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


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