{"record":{"id":"5b7d1a741c8a4f29","repo":"golangci/golangci-lint","slug":"can-t-get-file-s-contents-w","errorCode":null,"errorMessage":"can't get file %s contents: %w","messagePattern":"can't get file (.+?) contents: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/golinters/misspell/misspell.go","lineNumber":86,"sourceCode":"\t}\n\n\t// It can panic.\n\treplacer.Compile()\n\n\treturn replacer, nil\n}\n\nfunc runMisspellOnFile(pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error {\n\tposition, isGoFile := goanalysis.GetGoFilePosition(pass, file)\n\tif !isGoFile {\n\t\treturn nil\n\t}\n\n\t// Uses the non-adjusted file to work with cgo:\n\t// if we read the real file, the positions are wrong in some cases.\n\tfileContent, err := pass.ReadFile(pass.Fset.PositionFor(file.Pos(), false).Filename)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"can't get file %s contents: %w\", position.Filename, err)\n\t}\n\n\t// `r.ReplaceGo` doesn't find issues inside strings: it searches only inside comments.\n\t// `r.Replace` searches all words: it treats input as a plain text.\n\t// The standalone misspell tool uses `r.Replace` by default.\n\tvar replace func(input string) (string, []misspell.Diff)\n\tswitch strings.ToLower(mode) {\n\tcase \"restricted\":\n\t\treplace = replacer.ReplaceGo\n\tdefault:\n\t\treplace = replacer.Replace\n\t}\n\n\tf := pass.Fset.File(file.Pos())\n\n\t_, diffs := replace(string(fileContent))\n\n\tfor _, diff := range diffs {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/golinters/misspell/misspell.go#L68-L104","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: linting a generated dir that is deleted mid-run\nlinters-settings:\n  misspell: {}\n# after\nissues:\n  exclude-dirs:\n    - generated-temp\n  exclude-files:\n    - \".+\\\\.pb\\\\.go$\"","handlingStrategy":"try-catch","validationCode":"if _, err := os.ReadFile(path); err != nil {\n    return fmt.Errorf(\"file %s unreadable before lint: %w\", path, err)\n}","typeGuard":null,"tryCatchPattern":"err := runMisspell(...)\nif err != nil && strings.Contains(err.Error(), \"can't get file\") {\n    // check wrapped cause: os.IsNotExist / permission, then skip or fix perms\n}","preventionTips":["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."],"tags":["golang","linter","misspell","file-io"],"backgroundTag":"file-read-failed","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}