wavetermdev/waveterm · error
backup metadata mismatch: expected %s, got %s
Error message
backup metadata mismatch: expected %s, got %s
What it means
RestoreBackup is a safety check: metadata.FullPath (the original absolute path recorded at backup time) must exactly equal the restoreToFileName argument. This error means the caller asked to restore a backup into a different file than it was taken from, so the library refuses to overwrite the wrong file. Note the 'expected/got' wording is inverted from what one might assume: 'expected' is restoreToFileName, 'got' is metadata.FullPath.
Source
Thrown at pkg/filebackup/filebackup.go:109
backupData, err := os.ReadFile(backupFilePath)
if err != nil {
return fmt.Errorf("failed to read backup file: %w", err)
}
metadataPath := backupFilePath[:len(backupFilePath)-4] + ".json"
metadataData, err := os.ReadFile(metadataPath)
if err != nil {
return fmt.Errorf("failed to read backup metadata: %w", err)
}
var metadata BackupMetadata
err = json.Unmarshal(metadataData, &metadata)
if err != nil {
return fmt.Errorf("failed to unmarshal backup metadata: %w", err)
}
if metadata.FullPath != restoreToFileName {
return fmt.Errorf("backup metadata mismatch: expected %s, got %s", restoreToFileName, metadata.FullPath)
}
var perm os.FileMode
_, err = fmt.Sscanf(metadata.Perm, "%o", &perm)
if err != nil {
return fmt.Errorf("failed to parse file permissions: %w", err)
}
err = os.WriteFile(restoreToFileName, backupData, perm)
if err != nil {
return fmt.Errorf("failed to restore file: %w", err)
}
return nil
}
func CleanupOldBackups() error {
backupBaseDir := filepath.Join(wavebase.GetWaveCachesDir(), "waveai-backups")View on GitHub (pinned to a4447c1563)
Solutions
- Pass the exact absolute path recorded in the .json sidecar's 'fullpath' field as restoreToFileName.
- If the original path legitimately moved, update the sidecar's fullpath (or the intended target logic) deliberately rather than bypassing the check.
- Normalize the path (filepath.Abs / EvalSymlinks) on both sides before comparing if callers may use different but equivalent forms.
- Read the .json sidecar to see what FullPath was recorded and reconcile which path is correct.
Example fix
// before
filebackup.RestoreBackup(bakPath, "notes.txt") // relative path mismatches
// after
target, _ := filepath.Abs("notes.txt")
filebackup.RestoreBackup(bakPath, target) // matches metadata.FullPath Defensive patterns
Strategy: validation
Validate before calling
metaData, _ := os.ReadFile(strings.TrimSuffix(backupFilePath, ".bak") + ".json")
var meta struct{ FullPath string `json:"fullpath"` }
json.Unmarshal(metaData, &meta)
target, _ := filepath.Abs(restoreTo)
if meta.FullPath != target {
return fmt.Errorf("restore target %q does not match backup origin %q", target, meta.FullPath)
} Try / catch
err := filebackup.RestoreBackup(backupPath, targetPath)
if err != nil {
if strings.Contains(err.Error(), "metadata mismatch") {
// read the sidecar's 'fullpath' and use it as the restore target
return fmt.Errorf("wrong restore target: %w", err)
}
return err
} Prevention
- Always pass the exact absolute path from the sidecar's 'fullpath' field
- Resolve symlinks and make paths absolute before comparing
- Don't attempt to restore a moved/renamed file under its new path without updating metadata
- Remember 'expected' in the message is your restoreToFileName, 'got' is the stored FullPath
When it happens
Trigger: Calling RestoreBackup with a restoreToFileName that differs byte-for-byte from the FullPath stored in the .json sidecar — e.g. relative vs absolute path, symlinked vs real path, path case differences, or the file was moved since backup.
Common situations: Passing a relative path like "notes.txt" instead of the absolute path stored at backup time; the project directory was moved/renamed; resolving through a symlink or bind mount so the string differs; renaming the file and trying to restore under the new name.
Related errors
- unmatched bracket at position %d
- invalid index at position %d: %v
- invalid key at position %d: %s
- path is not a directory
- Image too large (>5MB)
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/262d4c57c81ca374.
Report an issue: GitHub.