{"record":{"id":"2045013c209e7a9d","repo":"wavetermdev/waveterm","slug":"failed-to-restore-file-w","errorCode":null,"errorMessage":"failed to restore file: %w","messagePattern":"failed to restore file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filebackup/filebackup.go","lineNumber":120,"sourceCode":"\tvar metadata BackupMetadata\n\terr = json.Unmarshal(metadataData, &metadata)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to unmarshal backup metadata: %w\", err)\n\t}\n\n\tif metadata.FullPath != restoreToFileName {\n\t\treturn fmt.Errorf(\"backup metadata mismatch: expected %s, got %s\", restoreToFileName, metadata.FullPath)\n\t}\n\n\tvar perm os.FileMode\n\t_, err = fmt.Sscanf(metadata.Perm, \"%o\", &perm)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse file permissions: %w\", err)\n\t}\n\n\terr = os.WriteFile(restoreToFileName, backupData, perm)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to restore file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc CleanupOldBackups() error {\n\tbackupBaseDir := filepath.Join(wavebase.GetWaveCachesDir(), \"waveai-backups\")\n\n\tif _, err := os.Stat(backupBaseDir); os.IsNotExist(err) {\n\t\treturn nil\n\t}\n\n\tentries, err := os.ReadDir(backupBaseDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read backup directory: %w\", err)\n\t}\n\n\tcutoffTime := time.Now().Add(-BackupRetentionPeriod)","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filebackup/filebackup.go#L102-L138","documentation":"RestoreBackup's final step writes the backed-up contents back to restoreToFileName with the recorded permissions via os.WriteFile. This error wraps that write failing; the restore did not complete and the target file may be left unchanged or (if newly created) partially written.","triggerScenarios":"os.WriteFile(restoreToFileName, backupData, perm) fails: target directory unwritable, file locked by another process, read-only filesystem, disk full, or the target path is a directory.","commonSituations":"File open in an editor/another process with a write lock (common on Windows); project directory made read-only; the original file was deleted and its directory is no longer writable; disk quota exhausted.","solutions":["Close any process holding the target file open and retry the restore.","Check write permissions on the target file and its containing directory (and that the target is a file, not a directory).","Free disk space / check quota on the target filesystem.","If the directory is read-only, restore to a writable location by copying the .bak manually, or fix mount permissions."],"exampleFix":"// before\nchmod 444 notes.txt && restore  # WriteFile fails: permission denied\n// after\nchmod 644 notes.txt  # or restore, then re-apply perms (restore sets perm itself)","handlingStrategy":"try-catch","validationCode":"if fi, err := os.Stat(restoreTo); err == nil && fi.IsDir() {\n    return fmt.Errorf(\"restore target %s is a directory\", restoreTo)\n}\nif dir := filepath.Dir(restoreTo); !writable(dir) {\n    return fmt.Errorf(\"directory %s not writable\", dir)\n}","typeGuard":null,"tryCatchPattern":"err := filebackup.RestoreBackup(backupPath, targetPath)\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && (errors.Is(perr.Err, syscall.EACCES) || errors.Is(perr.Err, syscall.EBUSY)) {\n        return fmt.Errorf(\"close programs using %s or fix permissions, then retry: %w\", targetPath, err)\n    }\n    return err\n}","preventionTips":["Close editors/processes holding the target file before restoring","Verify the target directory is writable and the target is not a directory","Check disk space and quota on the target filesystem","Retry restores after fixing EACCES/EBUSY rather than editing files by hand"],"tags":["filesystem","permissions","restore","write"],"backgroundTag":"file-write-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}