gastownhall/beads · error

backup destination does not exist: %w

Error message

backup destination does not exist: %w

What it means

Returned by EmbeddedDoltStore.BackupDatabase when the destination directory passed to it cannot be stat-ed, meaning it does not exist (or is otherwise inaccessible). Dolt file:// backups require an existing local directory, so the store fails fast with the underlying os.Stat error wrapped.

Source

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

func (s *EmbeddedDoltStore) BackupSync(ctx context.Context, name string) error {
	return s.withMutatingDBConn(ctx, func(db versioncontrolops.DBConn) error {
		return versioncontrolops.BackupSync(ctx, db, name)
	})
}

func (s *EmbeddedDoltStore) BackupRemove(ctx context.Context, name string) error {
	return s.withMutatingDBConn(ctx, func(db versioncontrolops.DBConn) error {
		return versioncontrolops.BackupRemove(ctx, db, name)
	})
}

// BackupDatabase registers dir as a file:// Dolt backup remote and syncs
// the database to it. The dir must exist locally. This preserves full Dolt
// commit history.
func (s *EmbeddedDoltStore) BackupDatabase(ctx context.Context, dir string) error {
	info, err := os.Stat(dir)
	if err != nil {
		return fmt.Errorf("backup destination does not exist: %w", err)
	}
	if !info.IsDir() {
		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.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Create the directory first: mkdir -p <dir> (BackupDatabase requires it to pre-exist)
  2. Fix typos and use absolute paths for the backup destination
  3. Check mount status and permissions on the target path
  4. Ensure the bd process user can read/write the directory

Example fix

// before
err := store.BackupDatabase(ctx, "/backups/beads")
// after
if err := os.MkdirAll("/backups/beads", 0o755); err != nil { return err }
err = store.BackupDatabase(ctx, "/backups/beads")
Defensive patterns

Strategy: validation

Validate before calling

func ensureBackupDir(dir string) error {
    info, err := os.Stat(dir)
    if err != nil {
        if os.IsNotExist(err) { return os.MkdirAll(dir, 0o755) }
        return err
    }
    if !info.IsDir() { return fmt.Errorf("%%s is not a directory", dir) }
    return nil
}

Try / catch

if err := store.BackupDatabase(ctx, dir); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && os.IsNotExist(pe) { /* create dir and retry */ }
}

Prevention

When it happens

Trigger: Calling BackupDatabase(ctx, dir) with a dir that does not exist, has a typo'd path, or is unreadable due to permissions — os.Stat returns an error which is wrapped verbatim.

Common situations: Typo in backup path; relative path resolved from the wrong working directory; backup volume not mounted in a container; permission denied on the target directory.

Related errors


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