wavetermdev/waveterm · error

failed to write backup file

Error message

failed to write backup file: %w

What it means

After creating the dated backup directory, MakeFileBackup writes the original file's contents to <basename>.<dirhash8>.<uuid>.bak with mode 0600 via os.WriteFile. This error wraps a failure of that write, meaning the backup file could not be created and the edit operation is aborted (no partial backup is returned).

Solutions

  1. Free disk space on the volume holding the Wave caches dir and retry the edit.
  2. Check permissions/ownership of the dated backup directory and ensure the process can create files in it.
  3. Verify the file being backed up is not larger than available space/quota; if the cache volume is unreliable, point WAVE_HOME at a local disk.
  4. Retry the operation; if it recurs, inspect OS logs for I/O errors on the cache volume.

Example fix

// before
df -h ~/.cache  # disk full
// after
rm -rf ~/.cache/waveterm/waveai-backups/*/  # or free space, then retry the edit
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(filepath.Dir(wavebase.GetWaveCachesDir(), "waveai-backups")); err == nil && !fi.IsDir() {
    return fmt.Errorf("backup path is not a directory")
}
// optionally check free space before large edits

Try / catch

backupPath, err := filebackup.MakeFileBackup(absPath)
if err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ENOSPC) {
        return fmt.Errorf("disk full: free space before editing %s", absPath)
    }
    return err
}

Prevention

When it happens

Trigger: os.WriteFile(backupPath, fileData, 0600) fails: disk full, quota exceeded, backup dir deleted between MkdirAll and write, permission denied, or I/O error on the cache volume.

Common situations: Disk quota exceeded on the home/cache partition while backing up a large file; antivirus or backup software locking files (Windows); cache dir on a network mount that dropped; race with CleanupOldBackups or manual deletion.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/1a924c7c0ed96581. Report an issue: GitHub.

Appendix: source

Thrown at pkg/filebackup/filebackup.go:65

		return "", fmt.Errorf("failed to generate UUID: %w", err)
	}
	uuidStr := uuidV7.String()

	now := time.Now()
	dateStr := now.Format("2006-01-02")

	backupDir := filepath.Join(wavebase.GetWaveCachesDir(), "waveai-backups", dateStr)
	err = os.MkdirAll(backupDir, 0700)
	if err != nil {
		return "", fmt.Errorf("failed to create backup directory: %w", err)
	}

	backupName := fmt.Sprintf("%s.%s.%s.bak", basename, dirHash8, uuidStr)
	backupPath := filepath.Join(backupDir, backupName)

	err = os.WriteFile(backupPath, fileData, 0600)
	if err != nil {
		return "", fmt.Errorf("failed to write backup file: %w", err)
	}

	metadata := BackupMetadata{
		FullPath:  absFilePath,
		Timestamp: now.Format(time.RFC3339),
		Perm:      fmt.Sprintf("%04o", fileInfo.Mode().Perm()),
	}

	metadataJSON, err := json.MarshalIndent(metadata, "", "  ")
	if err != nil {
		return "", fmt.Errorf("failed to marshal backup metadata: %w", err)
	}

	metadataName := fmt.Sprintf("%s.%s.%s.json", basename, dirHash8, uuidStr)
	metadataPath := filepath.Join(backupDir, metadataName)

	err = os.WriteFile(metadataPath, metadataJSON, 0600)
	if err != nil {

View on GitHub (pinned to a4447c1563)