golangci/golangci-lint · error

%s is not a directory

Error message

%s is not a directory

What it means

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.

Source

Thrown at pkg/commands/internal/dirhash.go:70

			// Skip vendor and node directories.
			case "vendor", "node_modules":
				return filepath.SkipDir

			// Skip VCS directories.
			case ".bzr", ".git", ".hg", ".svn":
				return filepath.SkipDir
			}

			// Skip submodules (directories containing go.mod files).
			if goModInfo, err := os.Lstat(filepath.Join(dir, "go.mod")); err == nil && !goModInfo.IsDir() {
				return filepath.SkipDir
			}

			return nil
		}

		if file == dir {
			return fmt.Errorf("%s is not a directory", dir)
		}

		if !info.Mode().IsRegular() {
			return nil
		}

		rel := file

		if dir != "." {
			rel = file[len(dir)+1:]
		}

		f := filepath.Join(prefix, rel)

		files = append(files, filepath.ToSlash(f))

		return nil
	})

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Pass a directory path (not a file) to the hashing command/function
  2. Verify the target with os.Stat and info.IsDir() before invoking
  3. Fix typos or stale variables in scripts/Makefile computing the path
  4. Resolve symlinks (filepath.EvalSymlinks) that may point at a regular file

Example fix

// before
hash, err := dirhashHash("./bin/golangci-lint") // file, not dir
// after
hash, err := dirhashHash("./bin/")
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(target)
if err != nil {
	return fmt.Errorf("stat %s: %w", target, err)
}
if !info.IsDir() {
	return fmt.Errorf("%s is not a directory", target)
}

Type guard

func isDir(path string) bool {
	info, err := os.Stat(path)
	return err == nil && info.IsDir()
}

Try / catch

if err := hashDir(target); err != nil {
	if strings.Contains(err.Error(), "is not a directory") {
		return fmt.Errorf("invalid directory argument %q", target)
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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