golangci/golangci-lint · error
create temporary directory: %w
Error message
create temporary directory: %w
What it means
customCommand.runE builds a custom golangci-lint binary and first creates a temporary working directory with os.MkdirTemp(os.TempDir(), "custom-gcl"). If directory creation fails, the error is wrapped as "create temporary directory: %w". The temp dir is normally cleaned up afterwards unless the keep-temp-files env var is set.
Source
Thrown at pkg/commands/custom.go:88
if c.opts.destination != "" {
cfg.Destination = c.opts.destination
}
err = cfg.Validate()
if err != nil {
return err
}
c.cfg = cfg
return nil
}
func (c *customCommand) runE(cmd *cobra.Command, _ []string) error {
tmp, err := os.MkdirTemp(os.TempDir(), "custom-gcl")
if err != nil {
return fmt.Errorf("create temporary directory: %w", err)
}
defer func() {
if os.Getenv(envKeepTempFiles) != "" {
log.Printf("WARN: The env var %s has been detected: the temporary directory is preserved: %s", envKeepTempFiles, tmp)
return
}
_ = os.RemoveAll(tmp)
}()
err = internal.NewBuilder(c.log, c.cfg, tmp).Build(cmd.Context())
if err != nil {
return fmt.Errorf("build process: %w", err)
}
return nilView on GitHub (pinned to ed7a235d2d)
Solutions
- Check the wrapped %w error (os.PathError) for the path and errno (ENOENT, EACCES, ENOSPC)
- Verify/set TMPDIR to an existing writable directory (echo $TMPDIR; mkdir -p $TMPDIR)
- Free disk space if the error is 'no space left on device'
- In restricted containers, ensure /tmp (or $TMPDIR) is mounted writable
- Clear out leftover custom-gcl* directories if /tmp is cluttered
Example fix
// before (CI) TMPDIR=/nonexistent golangci-lint custom // create temporary directory: mkdir /nonexistent/custom-gcl...: no such file or directory // after export TMPDIR=$(mktemp -d) golangci-lint custom
Defensive patterns
Strategy: fallback
Validate before calling
tmpBase := os.TempDir()
if info, err := os.Stat(tmpBase); err != nil || !info.IsDir() {
return fmt.Errorf("temp dir %s unusable (check TMPDIR)", tmpBase)
}
probe, err := os.CreateTemp(tmpBase, "write-probe")
if err != nil {
return fmt.Errorf("temp dir %s not writable: %w", tmpBase, err)
}
_ = os.Remove(probe.Name())
_ = probe.Close() Type guard
func isMkdirTempError(err error) (string, bool) {
var pe *os.PathError
if errors.As(err, &pe) {
return pe.Path, true
}
return "", false
} Try / catch
tmp, err := os.MkdirTemp(os.TempDir(), "custom-gcl")
if err != nil {
if errors.Is(err, fs.ErrPermission) || errors.Is(err, syscall.ENOSPC) {
return fmt.Errorf("fix TMPDIR or free disk space: %w", err)
}
return fmt.Errorf("create temporary directory: %w", err)
} Prevention
- Ensure TMPDIR points to an existing writable directory, especially in CI and containers
- Monitor disk space; temp-based builds fail fast when the disk fills
- Clean leftover custom-gcl* directories periodically
- In hardened environments, whitelist the temp dir for writes (SELinux/AppArmor)
When it happens
Trigger: os.MkdirTemp(os.TempDir(), "custom-gcl") fails while running the custom subcommand — TMPDIR points to a nonexistent/unwritable location, disk full, or too many open files.
Common situations: TMPDIR env var set to an invalid path in CI; read-only /tmp in containers; disk quota exceeded; SELinux/AppArmor blocking writes to the temp dir; /tmp filled by prior failed builds.
Related errors
- write file %s: %w
- failed to expand configuration path
- can't get config directory
- cgo preprocessing failed
- failed to remove dir %s: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/c0150e9a5effc1de.
Report an issue: GitHub.