golangci/golangci-lint · error
can't get file %s contents: %w
Error message
can't get file %s contents: %w
What it means
runMisspellOnFile reads the raw file from disk (using the non-adjusted position filename so cgo files resolve correctly) so the misspell replacer can scan comments and strings. If the OS read fails, the error is wrapped with the file path and aborts the misspell pass.
Source
Thrown at pkg/golinters/misspell/misspell.go:86
}
// It can panic.
replacer.Compile()
return replacer, nil
}
func runMisspellOnFile(pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error {
position, isGoFile := goanalysis.GetGoFilePosition(pass, file)
if !isGoFile {
return nil
}
// Uses the non-adjusted file to work with cgo:
// if we read the real file, the positions are wrong in some cases.
fileContent, err := pass.ReadFile(pass.Fset.PositionFor(file.Pos(), false).Filename)
if err != nil {
return fmt.Errorf("can't get file %s contents: %w", position.Filename, err)
}
// `r.ReplaceGo` doesn't find issues inside strings: it searches only inside comments.
// `r.Replace` searches all words: it treats input as a plain text.
// The standalone misspell tool uses `r.Replace` by default.
var replace func(input string) (string, []misspell.Diff)
switch strings.ToLower(mode) {
case "restricted":
replace = replacer.ReplaceGo
default:
replace = replacer.Replace
}
f := pass.Fset.File(file.Pos())
_, diffs := replace(string(fileContent))
for _, diff := range diffs {View on GitHub (pinned to ed7a235d2d)
Solutions
- Confirm the file exists and is readable at the reported path; fix permissions (chmod/chown).
- Re-run the linter to rule out a transient race with code generation or cleanup.
- Exclude generated/temporary files via skip-files so misspell doesn't read them.
- Check the wrapped %w cause for the exact OS error (ENOENT, EACCES, etc.) and fix storage/mount issues accordingly.
Example fix
# before: linting a generated dir that is deleted mid-run
linters-settings:
misspell: {}
# after
issues:
exclude-dirs:
- generated-temp
exclude-files:
- ".+\\.pb\\.go$" Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.ReadFile(path); err != nil {
return fmt.Errorf("file %s unreadable before lint: %w", path, err)
} Try / catch
err := runMisspell(...)
if err != nil && strings.Contains(err.Error(), "can't get file") {
// check wrapped cause: os.IsNotExist / permission, then skip or fix perms
} Prevention
- Don't delete/move source files while the linter runs.
- Fix file permissions so the lint user can read all targets.
- Exclude generated or ephemeral files via skip-files.
- Avoid linting directly off flaky network mounts; lint a local checkout.
When it happens
Trigger: pass.ReadFile fails for the file at pass.Fset.PositionFor(file.Pos(), false).Filename — file deleted/moved after parsing, permission denied, or I/O error on a network/removable drive.
Common situations: Files removed between lint start and run (race with build cleanup), unreadable files due to permissions or encryption, linting over flaky network mounts or Docker volume races in CI.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- unknown locale: %q
- process extra words: %w
- typo (%q) and correction (%q) fields should not be empty
- the word %q in the 'typo' field should only contain letters
- the word %q in the 'correction' field should only contain le
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/5b7d1a741c8a4f29.
Report an issue: GitHub.