golangci/golangci-lint · error

failed to remove dir %s: %w

Error message

failed to remove dir %s: %w

What it means

The cache clean command (cacheCommand.executeClean) resolves the default cache directory with cache.DefaultDir(), then removes it recursively with os.RemoveAll. If RemoveAll fails, the error is wrapped as "failed to remove dir %s: %w" so the developer knows which directory could not be deleted.

Source

Thrown at pkg/commands/cache.go:60

			Args:              cobra.NoArgs,
			ValidArgsFunction: cobra.NoFileCompletions,
			RunE:              c.executeStatus,
		},
	)

	c.cmd = cacheCmd

	return c
}

func (*cacheCommand) executeClean(_ *cobra.Command, _ []string) error {
	cacheDir, err := cache.DefaultDir()
	if err != nil {
		return err
	}

	if err := os.RemoveAll(cacheDir); err != nil {
		return fmt.Errorf("failed to remove dir %s: %w", cacheDir, err)
	}

	return nil
}

func (*cacheCommand) executeStatus(_ *cobra.Command, _ []string) error {
	cacheDir, err := cache.DefaultDir()
	if err != nil {
		return err
	}

	_, _ = fmt.Fprintf(logutils.StdOut, "Dir: %s\n", cacheDir)

	cacheSizeBytes, err := dirSizeBytes(cacheDir)
	if err == nil {
		_, _ = fmt.Fprintf(logutils.StdOut, "Size: %s\n", fsutils.PrettifyBytesCount(cacheSizeBytes))
	}

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Check permissions on the reported cache directory (ls -ld) and fix ownership (chown) or run with sufficient privileges
  2. Stop other instances of the tool that may hold files in the cache open, then retry
  3. If the path is a read-only or mounted volume, unmount or point the cache elsewhere via its config/env override
  4. Read the wrapped %w error (os.PathError) to see the exact failing path and errno (EACCES, EBUSY, EROFS)

Example fix

// before
$ golangci-lint cache clean
// failed to remove dir /root/.cache/golangci-lint: permission denied

// after
$ sudo chown -R $(whoami) /root/.cache/golangci-lint
$ golangci-lint cache clean  # succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

cacheDir, err := cache.DefaultDir()
if err != nil {
    return err
}
if info, err := os.Stat(cacheDir); err != nil {
    return fmt.Errorf("cache dir %s not accessible: %w", cacheDir, err)
} else if info.Mode().Perm()&0200 == 0 {
    return fmt.Errorf("cache dir %s not writable by current user", cacheDir)
}

Type guard

var pathErr *os.PathError
if errors.As(err, &pathErr) {
    if errors.Is(pathErr.Err, fs.ErrPermission) { /* advise chown/sudo */ }
    if errors.Is(pathErr.Err, syscall.EBUSY) { /* advise stopping other processes */ }
}

Try / catch

if err := os.RemoveAll(cacheDir); err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
        return fmt.Errorf("insufficient permissions to remove %s: %w", cacheDir, err)
    }
    return fmt.Errorf("failed to remove dir %s: %w", cacheDir, err)
}

Prevention

When it happens

Trigger: Running the cache clean subcommand when os.RemoveAll(cacheDir) cannot delete the cache directory or its contents.

Common situations: Permission denied (cache dir owned by root or another user, read-only filesystem); a file inside the cache is held open or locked by another running process; directory mounted (e.g. in a container volume) and cannot be unlinked; disk in a bad state.

Related errors


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