{"record":{"id":"cf975231f1309f8b","repo":"golangci/golangci-lint","slug":"s-is-not-a-directory","errorCode":null,"errorMessage":"%s is not a directory","messagePattern":"(.+?) is not a directory","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/dirhash.go","lineNumber":70,"sourceCode":"\t\t\t// Skip vendor and node directories.\n\t\t\tcase \"vendor\", \"node_modules\":\n\t\t\t\treturn filepath.SkipDir\n\n\t\t\t// Skip VCS directories.\n\t\t\tcase \".bzr\", \".git\", \".hg\", \".svn\":\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\t// Skip submodules (directories containing go.mod files).\n\t\t\tif goModInfo, err := os.Lstat(filepath.Join(dir, \"go.mod\")); err == nil && !goModInfo.IsDir() {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\n\t\tif file == dir {\n\t\t\treturn fmt.Errorf(\"%s is not a directory\", dir)\n\t\t}\n\n\t\tif !info.Mode().IsRegular() {\n\t\t\treturn nil\n\t\t}\n\n\t\trel := file\n\n\t\tif dir != \".\" {\n\t\t\trel = file[len(dir)+1:]\n\t\t}\n\n\t\tf := filepath.Join(prefix, rel)\n\n\t\tfiles = append(files, filepath.ToSlash(f))\n\n\t\treturn nil\n\t})","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/dirhash.go#L52-L88","documentation":"dirhash.go validates that the path given to a directory-hashing walk is actually a directory. When the walk root resolves to the same plain file it was handed (file == dir), it returns this error naming the offending path. It guards the hasher against hashing a regular file as if it were a directory tree.","triggerScenarios":"Calling the dirhash helper with a path that resolves to a regular file rather than a directory; the walker receives the root itself as an entry and file == dir matches.","commonSituations":"Passing a file path (e.g. ./bin/golangci-lint or a tarball) where a directory is expected in scripts or CI; typos in the directory argument; a symlink pointing at a regular file.","solutions":["Pass a directory path (not a file) to the hashing command/function","Verify the target with os.Stat and info.IsDir() before invoking","Fix typos or stale variables in scripts/Makefile computing the path","Resolve symlinks (filepath.EvalSymlinks) that may point at a regular file"],"exampleFix":"// before\nhash, err := dirhashHash(\"./bin/golangci-lint\") // file, not dir\n// after\nhash, err := dirhashHash(\"./bin/\")","handlingStrategy":"validation","validationCode":"info, err := os.Stat(target)\nif err != nil {\n\treturn fmt.Errorf(\"stat %s: %w\", target, err)\n}\nif !info.IsDir() {\n\treturn fmt.Errorf(\"%s is not a directory\", target)\n}","typeGuard":"func isDir(path string) bool {\n\tinfo, err := os.Stat(path)\n\treturn err == nil && info.IsDir()\n}","tryCatchPattern":"if err := hashDir(target); err != nil {\n\tif strings.Contains(err.Error(), \"is not a directory\") {\n\t\treturn fmt.Errorf(\"invalid directory argument %q\", target)\n\t}\n\treturn err\n}","preventionTips":["Always pass directory paths, never file paths, to dirhash helpers","Validate with os.Stat/IsDir before invoking","Clean user-supplied paths with filepath.Clean","Check symlink targets with filepath.EvalSymlinks"],"tags":["filesystem","go","validation"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}