wavetermdev/waveterm · error
failed to write temp file %q: %w (also failed to remove temp
Error message
failed to write temp file %q: %w (also failed to remove temp file: %v)
What it means
AtomicWriteFile first writes the data to a temp file (<fileName>.tmp). If that write fails AND cleanup of the temp file also fails, the write error is wrapped together with the removal error so the developer sees both failures. The target file was never touched.
Source
Thrown at pkg/util/fileutil/fileutil.go:183
if mode&charDevice == charDevice {
return "character-special"
}
if mode&os.ModeDevice == os.ModeDevice {
return "block-special"
}
}
ext := strings.ToLower(filepath.Ext(path))
if mimeType, ok := StaticMimeTypeMap[ext]; ok {
return mimeType
}
return ""
}
func AtomicWriteFile(fileName string, data []byte, perm os.FileMode) error {
tmpFileName := fileName + TempFileSuffix
if err := os.WriteFile(tmpFileName, data, perm); err != nil {
if removeErr := os.Remove(tmpFileName); removeErr != nil && !os.IsNotExist(removeErr) {
return fmt.Errorf("failed to write temp file %q: %w (also failed to remove temp file: %v)", tmpFileName, err, removeErr)
}
return err
}
if err := os.Rename(tmpFileName, fileName); err != nil {
if removeErr := os.Remove(tmpFileName); removeErr != nil && !os.IsNotExist(removeErr) {
return fmt.Errorf("failed to rename temp file %q to %q: %w (also failed to remove temp file: %v)", tmpFileName, fileName, err, removeErr)
}
return err
}
return nil
}
var (
systemBinDirs = []string{
"/bin/",
"/usr/bin/",
"/usr/local/bin/",
"/opt/bin/",View on GitHub (pinned to a4447c1563)
Solutions
- Fix write permissions on the parent directory (chmod/chown) so both writing and removing the temp file succeed.
- Check disk space (df) and free space on the filesystem holding the file.
- Ensure fileName + ".tmp" is not a directory or owned by another process; remove the stale temp file manually.
- Retry the write after fixing the underlying condition, then re-run AtomicWriteFile.
Example fix
// before
err := fileutil.AtomicWriteFile("/etc/hosts", data, 0644) // permission denied, temp cleanup also denied
// after
if err := os.Chmod(filepath.Dir(target), 0755); err != nil { return err }
err := fileutil.AtomicWriteFile(target, data, 0644) Defensive patterns
Strategy: try-catch
Validate before calling
// precheck writability of the target directory
d := filepath.Dir(fileName)
if fi, err := os.Stat(d); err != nil || !fi.IsDir() {
return fmt.Errorf("bad target dir %s", d)
}
if err := syscall.Access(d, unix.W_OK); err != nil {
return fmt.Errorf("dir %s not writable: %w", d, err)
} Try / catch
// Go: inspect wrapped errors
if err := fileutil.AtomicWriteFile(f, data, 0644); err != nil {
if strings.Contains(err.Error(), "failed to write temp file") {
log.Printf("temp write failed (and cleanup failed): %v", err)
// check permissions/disk space, remove stale <f>.tmp, retry
}
} Prevention
- Ensure the target directory is writable by the process user
- Monitor disk space on volumes holding config files
- Remove stale *.tmp files after crashes
- Avoid pointing AtomicWriteFile at paths owned by other users
When it happens
Trigger: Calling AtomicWriteFile where writing fileName+".tmp" fails (bad permissions, read-only dir, disk full, path is a directory) and the subsequent os.Remove of the temp file also fails with a non-NotNotExist error (e.g. permission denied on the directory).
Common situations: Writing to a directory without write permission; disk full so even unlink bookkeeping/attributes fail; temp file path colliding with a directory or a file owned by another user.
Related errors
- failed to rename temp file %q to %q: %w (also failed to remo
- failed to get app directory: %w
- failed to get builder executable path: %w
- build output not found: %w
- failed to read app manifest: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f483f9a3776736ba.
Report an issue: GitHub.