wavetermdev/waveterm · error

failed to stat file for backup: %w

Error message

failed to stat file for backup: %w

What it means

MakeFileBackup snapshots a file before Wave modifies it (write/edit/delete text-file callbacks). It first calls os.Stat on the absolute path; if the file cannot be stat'd (missing, permission denied, or bad path), this wrapped error is returned and no backup is made, so the operation is aborted before modifying the file.

Source

Thrown at pkg/filebackup/filebackup.go:31

	"path/filepath"
	"time"

	"github.com/google/uuid"
	"github.com/wavetermdev/waveterm/pkg/wavebase"
)

const BackupRetentionPeriod = 5 * 24 * time.Hour

type BackupMetadata struct {
	FullPath  string `json:"fullpath"`
	Timestamp string `json:"timestamp"`
	Perm      string `json:"perm"`
}

func MakeFileBackup(absFilePath string) (string, error) {
	fileInfo, err := os.Stat(absFilePath)
	if err != nil {
		return "", fmt.Errorf("failed to stat file for backup: %w", err)
	}

	fileData, err := os.ReadFile(absFilePath)
	if err != nil {
		return "", fmt.Errorf("failed to read file for backup: %w", err)
	}

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

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the file still exists before issuing the write/edit/delete (refresh the file listing)
  2. Check path spelling and that it is absolute and on a mounted filesystem
  3. Fix permissions on the file and its parent directories
  4. If delete raced, treat the missing file as already-deleted and retry or ignore

Example fix

// before
backupPath, err := filebackup.MakeFileBackup(path)
// after
if _, err := os.Stat(path); os.IsNotExist(err) {
    return nil // nothing to back up; file already gone
}
backupPath, err := filebackup.MakeFileBackup(path)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(absFilePath); err != nil {
    // file missing/unreadable — skip backup or treat delete as already done
}

Try / catch

backupPath, err := filebackup.MakeFileBackup(path)
if err != nil {
    if os.IsNotExist(errors.Unwrap(err)) {
        return nil // nothing to back up; file already gone
    }
    return err
}

Prevention

When it happens

Trigger: os.Stat(absFilePath) fails: file already deleted (e.g. deleteTextFileCallback racing another delete), wrong/relative path passed, or permission denied on a parent directory.

Common situations: Two clients deleting/editing the same file concurrently; file removed outside Wave between listing and the edit; symlink to a non-existent target; case-sensitivity mismatch on path.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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