wavetermdev/waveterm · error

failed to create backup directory: %w

Error message

failed to create backup directory: %w

What it means

MakeFileBackup stores AI-file-edit backups under the Wave caches dir (waveai-backups/<YYYY-MM-DD>). Before writing any backup it creates that dated directory with os.MkdirAll(0700). This error wraps the underlying os.MkdirAll failure, meaning the backup directory tree could not be created and no backup was taken (the calling write/edit/delete callback aborts).

Source

Thrown at pkg/filebackup/filebackup.go:57

	dir := filepath.Dir(absFilePath)
	basename := filepath.Base(absFilePath)

	hash := sha256.Sum256([]byte(dir))
	dirHash8 := hex.EncodeToString(hash[:])[:8]

	uuidV7, err := uuid.NewV7()
	if err != nil {
		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 {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check permissions and ownership of the Wave caches directory (wavebase.GetWaveCachesDir()) and ensure it is writable by the current user.
  2. Verify no regular file exists at waveai-backups or at the dated subdirectory path that would block MkdirAll; remove or rename it.
  3. Check disk space and mount status (df -h) if the cache volume is full or read-only.
  4. If WAVE_HOME/custom cache config was changed, reset it to a valid writable path and retry the operation.

Example fix

// before: caches dir not writable, MkdirAll fails silently to the user
os.Chmod(cacheDir, 0500)
// after: ensure the cache dir is writable before running Wave
os.Chmod(cacheDir, 0700)
Defensive patterns

Strategy: validation

Validate before calling

cacheDir := wavebase.GetWaveCachesDir()
if fi, err := os.Stat(cacheDir); err != nil || !fi.IsDir() {
    return fmt.Errorf("wave caches dir %s unavailable: %w", cacheDir, err)
}
if err := syscall.Access(cacheDir, unix.W_OK); err != nil {
    return fmt.Errorf("wave caches dir %s not writable: %w", cacheDir, err)
}

Try / catch

backupPath, err := filebackup.MakeFileBackup(absPath)
if err != nil {
    if strings.Contains(err.Error(), "failed to create backup directory") {
        // proceed without backup or surface a clear "backup storage unavailable" message
        log.Warnf("backup skipped: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling MakeFileBackup (via writeTextFileCallback, editTextFileCallback, or deleteTextFileCallback) when os.MkdirAll(GetWaveCachesDir()/waveai-backups/<date>, 0700) fails: caches dir unwritable, path component is a file not a directory, or disk/permission errors.

Common situations: WAVE_HOME or cache directory pointing at a read-only or non-existent location; another process created a file named 'waveai-backups' or the date directory; running with a different user than the cache dir owner; full or read-only filesystem.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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