golangci/golangci-lint · error
failed to build packages cache: %w
Error message
failed to build packages cache: %w
What it means
Before linting, golangci-lint builds an on-disk packages cache (`cache.NewCache`). If cache initialization fails — typically because the user cache directory cannot be determined or created — the error is wrapped as `failed to build packages cache: %w`. Without this cache the run cannot proceed.
Source
Thrown at pkg/commands/run.go:203
}
c.dbManager = dbManager
c.printer, err = printers.NewPrinter(c.log, &c.cfg.Output.Formats, c.reportData, c.cfg.GetBasePath())
if err != nil {
return err
}
c.goenv = goutil.NewEnv(c.log.Child(logutils.DebugKeyGoEnv))
c.fileCache = fsutils.NewFileCache()
c.lineCache = fsutils.NewLineCache(c.fileCache)
sw := timeutils.NewStopwatch("pkgcache", c.log.Child(logutils.DebugKeyStopwatch))
pkgCache, err := cache.NewCache(sw, c.log.Child(logutils.DebugKeyPkgCache))
if err != nil {
return fmt.Errorf("failed to build packages cache: %w", err)
}
guard := load.NewGuard()
pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard)
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard)
if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil {
return fmt.Errorf("failed to init hash salt: %w", err)
}
if ok := c.acquireFileLock(); !ok {
return errors.New("parallel golangci-lint is running")
}
return nil
}View on GitHub (pinned to ed7a235d2d)
Solutions
- Set a writable cache dir: export XDG_CACHE_HOME (or HOME) to an existing writable path.
- Create the cache directory: mkdir -p ~/.cache/golangci-lint and fix permissions with chown/chmod.
- Run the container with a writable volume mounted at the cache location (e.g. -v gocache:/root/.cache).
- Check disk space if the error indicates a full filesystem.
- Inspect the wrapped error after the message for the precise OS-level cause.
Example fix
// before (CI step)
- run: golangci-lint run # HOME is unset in container
// after
- run: |
export HOME=/tmp && mkdir -p $HOME/.cache
golangci-lint run Defensive patterns
Strategy: validation
Validate before calling
// ensure a writable cache dir exists before running
cacheDir := os.Getenv("XDG_CACHE_HOME")
if cacheDir == "" {
home, err := os.UserHomeDir()
if err != nil { return err }
cacheDir = filepath.Join(home, ".cache")
}
if err := os.MkdirAll(filepath.Join(cacheDir, "golangci-lint"), 0o755); err != nil {
return fmt.Errorf("cache dir not usable: %w", err)
} Try / catch
if _, err := cache.NewCache(sw, log); err != nil {
return fmt.Errorf("failed to build packages cache: %w", err) // check HOME/XDG_CACHE_HOME
} Prevention
- Set HOME or XDG_CACHE_HOME explicitly in CI containers running as non-root.
- Mount a writable volume at the cache location in Docker.
- Create ~/.cache/golangci-lint with correct ownership in setup steps.
- Monitor disk space on runners.
When it happens
Trigger: `cache.NewCache` failing because the OS cache directory (e.g. $XDG_CACHE_HOME, ~/.cache, %LocalAppData%) is unset and home is undiscoverable, unwritable, or on a full/read-only filesystem.
Common situations: CI containers running as non-root without a writable HOME; XDG_CACHE_HOME pointing to a non-existent dir; read-only root filesystems in Docker; NFS-mounted homes with permission issues; `HOME` unset in cron/systemd jobs.
Related errors
- failed to remove dir %s: %w
- create destination directory: %w
- read directory: %w
- %s is not a directory
- write file %s: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/3fae522c03d57d98.
Report an issue: GitHub.