wavetermdev/waveterm · error

failed to write backup file: %w

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).

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)

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.