gastownhall/beads · error

atomicfile: chmod: %w

Error message

atomicfile: chmod: %w

What it means

Before renaming the temp file into place, atomicfile.Writer.Close calls f.Chmod(w.perm) because os.CreateTemp creates files with 0600. If the chmod syscall fails, Close removes the temp file and returns this wrapped error, leaving the target untouched.

Source

Thrown at internal/atomicfile/atomicfile.go:79

// Write delegates to the underlying temp file.
func (w *Writer) Write(p []byte) (int, error) {
	return w.f.Write(p)
}

// Close fsyncs the temp file and atomically renames it to the target path.
// After Close returns successfully, the target contains exactly the data
// written. On error the temp file is removed and the target is untouched.
func (w *Writer) Close() error {
	if w.done {
		return nil
	}
	w.done = true

	// Ensure permissions before rename — CreateTemp uses 0600 by default.
	if err := w.f.Chmod(w.perm); err != nil {
		_ = w.f.Close()
		_ = os.Remove(w.f.Name())
		return fmt.Errorf("atomicfile: chmod: %w", err)
	}

	if err := w.f.Sync(); err != nil {
		_ = w.f.Close()
		_ = os.Remove(w.f.Name())
		return fmt.Errorf("atomicfile: sync: %w", err)
	}

	if err := w.f.Close(); err != nil {
		_ = os.Remove(w.f.Name())
		return fmt.Errorf("atomicfile: close: %w", err)
	}

	if err := os.Rename(w.f.Name(), w.target); err != nil {
		_ = os.Remove(w.f.Name())
		return fmt.Errorf("atomicfile: rename: %w", err)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the write on a filesystem that supports permission changes (local ext4/APFS/NTFS rather than the problematic mount)
  2. Ensure Close is called exactly once per Writer to avoid operating on a closed fd
  3. If perm doesn't matter on your target, keep the default 0600 path but verify mount support
Defensive patterns

Strategy: try-catch

Try / catch

if err := w.Close(); err != nil {
    if strings.Contains(err.Error(), "atomicfile: chmod") {
        log.Printf("target fs may not support chmod: %v", err)
        // fall back to plain os.WriteFile or different mount
    }
    return err
}

Prevention

When it happens

Trigger: Closing a Writer whose file descriptor has become invalid (already closed elsewhere), or a filesystem/OS refusing the chmod (e.g. some FUSE/network mounts, or the file was deleted under the process).

Common situations: Writing atomic files on exotic mounts (NFS, some container volumes) that don't support chmod, or double-Close misuse of the Writer.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/cac0c517f3b8300e. Report an issue: GitHub.