henrygd/beszel · error
rename: %w
Error message
rename: %w
What it means
After chmod succeeds, downloadFile atomically moves the temp file to its final destination with os.Rename. A wrapped `rename: %w` error means the move failed and the temp file was deleted. Rename typically fails when source and destination are on different filesystems or the destination is not writable.
Source
Thrown at agent/tools/fetchsmartctl/main.go:120
}
if hasher != nil && shaHex != "" {
cleanSha := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(shaHex), " ", ""))
got := strings.ToLower(hex.EncodeToString(hasher.Sum(nil)))
if got != cleanSha {
os.Remove(tmp)
return fmt.Errorf("hash mismatch: got %s want %s", got, cleanSha)
}
}
// Make executable and move into place
if err := os.Chmod(tmp, 0o755); err != nil {
os.Remove(tmp)
return fmt.Errorf("chmod: %w", err)
}
if err := os.Rename(tmp, dest); err != nil {
os.Remove(tmp)
return fmt.Errorf("rename: %w", err)
}
fmt.Println("smartctl.exe downloaded to", dest)
return nil
}
func fatalf(format string, a ...any) {
fmt.Fprintf(os.Stderr, format+"\n", a...)
os.Exit(1)
}
View on GitHub (pinned to b38fb7dafa)
Solutions
- Ensure the destination directory exists and is writable (sufficient privileges or a user-writable path).
- Set TMPDIR (or the temp path) to a directory on the same filesystem as the destination to avoid EXDEV, or add a copy-based fallback.
- Retry if the cause was a transient lock (antivirus/another process); avoid running multiple instances concurrently.
- Read the wrapped error's errno: ENOENT → create dest dir; EXDEV → same-fs temp; EACCES → fix permissions.
Example fix
// before
if err := os.Rename(tmp, dest); err != nil {
return fmt.Errorf("rename: %w", err)
}
// after
if err := os.Rename(tmp, dest); err != nil {
if errors.Is(err, syscall.EXDEV) {
if cerr := copyFile(tmp, dest); cerr != nil {
return fmt.Errorf("rename: %w", err)
}
} else {
return fmt.Errorf("rename: %w", err)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure dest dir exists and temp and dest share a filesystem
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
return err
}
tmp := filepath.Join(filepath.Dir(dest), ".fetch-tmp") // same device as dest Try / catch
if err := downloadFile(url, dest, sha); err != nil {
if strings.HasPrefix(err.Error(), "rename:") {
log.Printf("rename failed (cross-device or locked dest?): %v", err)
} else {
return err
}
} Prevention
- Create the temp file next to the destination so rename stays on one device.
- MkdirAll the destination directory before download.
- Avoid concurrent runs writing the same destination.
- Check dest is writable before starting (access test).
When it happens
Trigger: os.Rename(tmp, dest) errors: temp dir and dest are on different mounts/devices (EXDEV), dest directory doesn't exist or lacks write permission, dest is locked by another process (Windows), or tmp vanished.
Common situations: TMPDIR on tmpfs while dest is on another disk; installing to a read-only or root-owned directory without privileges; concurrent runs racing over the same dest file; antivirus holding the file open.
Related errors
- chmod: %w
- failed to rename the current executable: %w
- failed replacing the executable: %w
- data directory not found
- fingerprint file is empty
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/1912d13221ff0509.
Report an issue: GitHub.