gastownhall/beads · error

sync to backup: %w

Error message

sync to backup: %w

What it means

Returned when BackupDatabase falls back to syncing via an existing backup remote that already points at the same URL (address-conflict path), and that BackupSync fails. The remote registration was skipped because another remote (e.g. "default" from `bd backup init`) owns the URL, but replicating data to it errored.

Source

Thrown at internal/storage/embeddeddolt/version_control.go:755

		return fmt.Errorf("backup destination is not a directory: %s", dir)
	}

	backupURL, err := versioncontrolops.DirToFileURL(dir)
	if err != nil {
		return err
	}
	backupName := "backup_export"

	return s.withMutatingDBConn(ctx, func(db versioncontrolops.DBConn) error {
		// Register as a backup remote (idempotent — remove first if exists).
		_ = versioncontrolops.BackupRemove(ctx, db, backupName)
		if err := versioncontrolops.BackupAdd(ctx, db, backupName, backupURL); err != nil {
			// Another backup (e.g. "default" registered by `bd backup init`) may
			// already point to this URL. In that case, sync using the existing
			// remote name rather than failing.
			if conflict := versioncontrolops.ExtractAddressConflictName(err); conflict != "" {
				if syncErr := versioncontrolops.BackupSync(ctx, db, conflict); syncErr != nil {
					return fmt.Errorf("sync to backup: %w", syncErr)
				}
				return nil
			}
			return fmt.Errorf("register backup remote: %w", err)
		}
		if err := versioncontrolops.BackupSync(ctx, db, backupName); err != nil {
			return fmt.Errorf("sync to backup: %w", err)
		}
		return nil
	})
}

// RestoreDatabase restores the database from a Dolt backup at dir.
// The dir must exist locally and contain a valid Dolt backup.
// When force is true, an existing database is overwritten.
func (s *EmbeddedDoltStore) RestoreDatabase(ctx context.Context, dir string, force bool) error {
	info, err := os.Stat(dir)
	if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check disk space and writability of the backup directory
  2. Inspect the wrapped syncErr root cause in the error chain
  3. Remove and re-register the conflicting backup remote if it points at a stale location
  4. Retry the backup after resolving filesystem issues
Defensive patterns

Strategy: try-catch

Validate before calling

// check backup dir is writable before syncing
probe := filepath.Join(dir, ".write-probe")
if err := os.WriteFile(probe, []byte("x"), 0o600); err != nil {
    return fmt.Errorf("backup dir not writable: %%w", err)
}
os.Remove(probe)

Try / catch

if err := store.BackupDatabase(ctx, dir); err != nil {
    if strings.Contains(err.Error(), "sync to backup") { /* filesystem-level issue: check space/permissions */ }
}

Prevention

When it happens

Trigger: BackupAdd returns an address conflict; ExtractAddressConflictName yields the existing remote name; BackupSync(ctx, db, conflict) then fails — permission denied writing to the backup dir, disk full, or Dolt backup engine error.

Common situations: Re-running backup against a dir already registered by `bd backup init`; backup drive full or read-only; corrupted existing backup directory refusing new writes.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/d9f889b2c3cd65c8. Report an issue: GitHub.