golangci/golangci-lint · error
writing file %s: %w
Error message
writing file %s: %w
What it means
This error is returned by writeNewFile in the migrate cloner when os.WriteFile fails to persist the formatted cloned configuration file to dstPath. The clone step of `golangci-lint migrate` copies and re-formats the old configuration, and any filesystem-level failure during the write is wrapped with the destination path for context. It indicates the migration aborted because the output file could not be written.
Source
Thrown at pkg/commands/internal/migrate/cloner/cloner.go:191
err := printer.Fprint(&buf, fset, file)
if err != nil {
return fmt.Errorf("printing %s: %w", srcPath, err)
}
dstPath := filepath.Join(dstDir, filepath.Base(srcPath))
_ = os.MkdirAll(filepath.Dir(dstPath), os.ModePerm)
formatted, err := imports.Process(dstPath, buf.Bytes(), nil)
if err != nil {
return fmt.Errorf("formatting %s: %w", dstPath, err)
}
//nolint:gosec,mnd // The permission is right.
err = os.WriteFile(dstPath, formatted, 0o644)
if err != nil {
return fmt.Errorf("writing file %s: %w", dstPath, err)
}
return nil
}
View on GitHub (pinned to ed7a235d2d)
Solutions
- Check that the parent directory of the destination file exists and is writable by the current user.
- Free disk space and re-run the migrate command.
- If the path is a directory or locked by another process, choose a different output path or close the locking process.
- Re-run with elevated permissions only if the target location genuinely requires them.
Example fix
// before
err = os.WriteFile(dstPath, formatted, 0o644)
// after
if err := os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil {
return fmt.Errorf("creating dir for %s: %w", dstPath, err)
}
if err := os.WriteFile(dstPath, formatted, 0o644); err != nil {
return fmt.Errorf("writing file %s: %w", dstPath, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil { return err }
if fi, err := os.Stat(dstPath); err == nil && fi.IsDir() { return fmt.Errorf("%s is a directory", dstPath) } Try / catch
if err := writeNewFile(dstPath, srcPath); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {
// handle permission problem on dstPath
}
return err
} Prevention
- Ensure the destination directory exists and is writable before running migrate.
- Watch free disk space in CI runners.
- Never point the migrate output at an existing directory.
When it happens
Trigger: os.WriteFile(dstPath, formatted, 0o644) returns an error: destination directory does not exist, read-only filesystem, permission denied, disk full, or dstPath is a directory.
Common situations: Running migrate in a read-only checkout, a directory owned by another user, a full disk (especially CI runners), or when the target output path collides with an existing directory.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
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/fed48d6c4bdcdab1.
Report an issue: GitHub.