golangci/golangci-lint · error
can't create file %s: %w
Error message
can't create file %s: %w
What it means
When CPU profiling is requested (--cpu-profile-path), `startTracing` creates the profile file with os.Create. If the file cannot be created, the error is wrapped as `can't create file %s: %w`. The path and underlying OS error are both included, so the cause is directly actionable.
Source
Thrown at pkg/commands/run.go:268
if err := c.runAndPrint(ctx); err != nil {
c.log.Errorf("Running error: %s", err)
if c.exitCode == exitcodes.Success {
if exitErr, ok := errors.AsType[*exitcodes.ExitError](err); ok {
c.exitCode = exitErr.Code
} else {
c.exitCode = exitcodes.Failure
}
}
}
c.setupExitCode(ctx)
}
func (c *runCommand) startTracing() error {
if c.opts.CPUProfilePath != "" {
f, err := os.Create(c.opts.CPUProfilePath)
if err != nil {
return fmt.Errorf("can't create file %s: %w", c.opts.CPUProfilePath, err)
}
if err := pprof.StartCPUProfile(f); err != nil {
return fmt.Errorf("can't start CPU profiling: %w", err)
}
}
if c.opts.MemProfilePath != "" {
if rate := os.Getenv(envMemProfileRate); rate != "" {
runtime.MemProfileRate, _ = strconv.Atoi(rate)
}
}
if c.opts.TracePath != "" {
f, err := os.Create(c.opts.TracePath)
if err != nil {
return fmt.Errorf("can't create file %s: %w", c.opts.TracePath, err)
}
if err = trace.Start(f); err != nil {View on GitHub (pinned to ed7a235d2d)
Solutions
- Create the parent directory of the profile path before running (mkdir -p).
- Point --cpu-profile-path at a writable location (e.g. /tmp/cpu.prof).
- Fix permissions on the target directory (chmod/chown) or run as a user with write access.
- Check the wrapped OS error after the message — 'no such file or directory' vs 'permission denied' vs 'is a directory' point to different fixes.
- Free disk space if the error indicates the filesystem is full.
Example fix
// before
- run: golangci-lint run --cpu-profile-path=profiles/cpu.prof # profiles/ missing
// after
- run: |
mkdir -p profiles
golangci-lint run --cpu-profile-path=profiles/cpu.prof Defensive patterns
Strategy: validation
Validate before calling
// verify the profile path's directory is writable before enabling profiling
profDir := filepath.Dir(cpuProfilePath)
if err := os.MkdirAll(profDir, 0o755); err != nil {
return fmt.Errorf("cannot create profile dir %s: %w", profDir, err)
} Try / catch
f, err := os.Create(c.opts.CPUProfilePath)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) {
log.Printf("create failed: path=%s op=%s err=%v", pe.Path, pe.Op, pe.Err)
}
return fmt.Errorf("can't create file %s: %w", c.opts.CPUProfilePath, err)
} Prevention
- mkdir -p the profile directory before passing --cpu-profile-path.
- Use a simple writable path like /tmp/cpu.prof.
- Don't point the flag at an existing directory.
- Check permissions when the linter runs under a different user in CI.
When it happens
Trigger: Passing --cpu-profile-path pointing to a non-existent directory, a path without write permission, or a path that is itself a directory; also disk-full or read-only filesystem conditions during os.Create.
Common situations: CI passing a profile path under a directory that was never created; typos in the path; running in a read-only container filesystem; permission mismatch when running the linter as a different user.
Related errors
- saving configuration file: %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/3ce64016ae28be34.
Report an issue: GitHub.