{"record":{"id":"241e4af7e21e16b7","repo":"wavetermdev/waveterm","slug":"failed-to-write-backup-metadata-w","errorCode":null,"errorMessage":"failed to write backup metadata: %w","messagePattern":"failed to write backup metadata: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/filebackup/filebackup.go","lineNumber":84,"sourceCode":"\t}\n\n\tmetadata := BackupMetadata{\n\t\tFullPath:  absFilePath,\n\t\tTimestamp: now.Format(time.RFC3339),\n\t\tPerm:      fmt.Sprintf(\"%04o\", fileInfo.Mode().Perm()),\n\t}\n\n\tmetadataJSON, err := json.MarshalIndent(metadata, \"\", \"  \")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to marshal backup metadata: %w\", err)\n\t}\n\n\tmetadataName := fmt.Sprintf(\"%s.%s.%s.json\", basename, dirHash8, uuidStr)\n\tmetadataPath := filepath.Join(backupDir, metadataName)\n\n\terr = os.WriteFile(metadataPath, metadataJSON, 0600)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to write backup metadata: %w\", err)\n\t}\n\n\treturn backupPath, nil\n}\n\nfunc RestoreBackup(backupFilePath string, restoreToFileName string) error {\n\tbackupData, err := os.ReadFile(backupFilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read backup file: %w\", err)\n\t}\n\n\tmetadataPath := backupFilePath[:len(backupFilePath)-4] + \".json\"\n\tmetadataData, err := os.ReadFile(metadataPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read backup metadata: %w\", err)\n\t}\n\n\tvar metadata BackupMetadata","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/filebackup/filebackup.go#L66-L102","documentation":"MakeFileBackup writes the .json metadata sidecar next to the .bak file (mode 0600). This error wraps os.WriteFile failing for the metadata file. The .bak file may already exist on disk but the backup is reported as failed because restore depends on the metadata sidecar.","triggerScenarios":"os.WriteFile(metadataPath, metadataJSON, 0600) fails after the .bak write succeeded: disk filled between the two writes, metadata path locked by another process, permission change on the backup dir, or I/O error.","commonSituations":"Disk reaching capacity mid-backup (barely enough for .bak, not for .json); on-demand antivirus scanning interfering on Windows; cache volume flaking out mid-operation.","solutions":["Free disk space on the cache volume and retry the operation.","Check the dated backup directory for stale/partial .bak files without .json sidecars and clean them up.","Check permissions on the backup directory and any file-locking software interference.","Retry; if recurring, verify filesystem health (fsck / chkdsk)."],"exampleFix":"// before\nls ~/.cache/waveterm/waveai-backups/2026-09-01/  # orphan *.bak without *.json\n// after\nfree disk space, delete orphaned *.bak files, and retry the edit","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"backupPath, err := filebackup.MakeFileBackup(absPath)\nif err != nil {\n    if strings.Contains(err.Error(), \"write backup metadata\") {\n        // backup .bak may be orphaned without its .json sidecar\n        log.Warnf(\"backup incomplete, orphaned .bak possible: %v\", err)\n    }\n    return err\n}","preventionTips":["Keep free disk space above the size of the largest edited file plus metadata","Never delete .json sidecars independently of .bak files","Check for orphaned *.bak without *.json in backup dirs after failures","Watch for I/O errors on the cache volume in system logs"],"tags":["filesystem","disk-full","backup","go"],"backgroundTag":"file-write-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}