wavetermdev/waveterm · warning

failed to parse file permissions: %w

Error message

failed to parse file permissions: %w

What it means

RestoreBackup parses the octal permission string recorded in metadata.Perm (formatted as %04o at backup time) into an os.FileMode using fmt.Sscanf("%o"). This error wraps Sscanf failing, meaning the Perm string is missing, empty, or not valid octal.

Source

Thrown at pkg/filebackup/filebackup.go:115

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

	if _, err := os.Stat(backupBaseDir); os.IsNotExist(err) {
		return nil
	}

	entries, err := os.ReadDir(backupBaseDir)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the 'perm' field in the .json sidecar and ensure it is a 3-4 digit octal string like "0644".
  2. Fix the perm value in the sidecar to the correct octal mode (or recreate the backup pair).
  3. Consider using strconv.ParseUint(metadata.Perm, 8, 32) in caller-side validation to pre-check before restore.
  4. Verify the sidecar came from the same version of the backup code (Perm format %04o).

Example fix

// before
"perm": "rw-r--r--"   // not octal, Sscanf %o fails
// after
"perm": "0644"        // valid octal
Defensive patterns

Strategy: validation

Validate before calling

metaData, _ := os.ReadFile(strings.TrimSuffix(backupFilePath, ".bak") + ".json")
var meta struct{ Perm string `json:"perm"` }
json.Unmarshal(metaData, &meta)
if _, err := strconv.ParseUint(meta.Perm, 8, 32); err != nil {
    return fmt.Errorf("invalid perm field %q in metadata", meta.Perm)
}

Try / catch

err := filebackup.RestoreBackup(backupPath, targetPath)
if err != nil {
    if strings.Contains(err.Error(), "parse file permissions") {
        return fmt.Errorf("metadata perm field invalid; fix sidecar or pick another backup: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: The .json sidecar has a missing/empty 'perm' field or a non-octal value — from a corrupted, truncated, or hand-edited metadata file, or a sidecar produced by incompatible code.

Common situations: Hand-edited metadata where perm was changed to e.g. "rwxr-xr-x" or ""; truncated JSON that unmarshaled to a zero-value struct with empty Perm; schema drift between backup writers.

Understand the failure class

Related errors


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