gastownhall/beads · error

dolt remote add failed: %s: %w

Error message

dolt remote add failed: %s: %w

What it means

After validating argv, AddCLIRemote executes `dolt remote add <name> <url>` with cmd.Dir set to dbPath. If the command exits non-zero or cannot start, the function returns dolt's combined stdout/stderr plus the exec error wrapped as "dolt remote add failed". This means the dolt subprocess itself rejected the operation or could not be run at all.

Source

Thrown at internal/storage/doltutil/remotes.go:168

	}
	return false
}

// AddCLIRemote adds a remote at the filesystem level via dolt CLI.
// Remote mutation should normally go through SQL; this is reserved for the
// local CLI mirror required by subprocess push/pull/fetch routing.
func AddCLIRemote(dbPath, name, url string) error {
	if err := remotecache.ValidateRemoteName(name); err != nil {
		return fmt.Errorf("invalid remote name: %w", err)
	}
	if err := remotecache.ValidateRemoteURL(url); err != nil {
		return fmt.Errorf("invalid remote URL: %w", err)
	}
	cmd := exec.Command("dolt", "remote", "add", name, url) // #nosec G204 -- validated argv
	cmd.Dir = dbPath
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("dolt remote add failed: %s: %w", strings.TrimSpace(string(out)), err)
	}
	return nil
}

// RemoveCLIRemote removes a remote at the filesystem level via dolt CLI.
func RemoveCLIRemote(dbPath, name string) error {
	if err := remotecache.ValidateRemoteName(name); err != nil {
		return fmt.Errorf("invalid remote name: %w", err)
	}
	cmd := exec.Command("dolt", "remote", "remove", name) // #nosec G204 -- validated argv
	cmd.Dir = dbPath
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("dolt remote remove failed: %s: %w", strings.TrimSpace(string(out)), err)
	}
	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the %s portion of the error message — it contains dolt's own diagnostic output for the failure
  2. Verify `dolt` is installed and on PATH (`dolt version` succeeds)
  3. Confirm dbPath holds an initialized dolt database (`dolt init` in dbPath if needed)
  4. Run `dolt remote -v` in dbPath; if the remote already exists, remove it or let the idempotent EnsureCLIRemote reconcile it
  5. Retry the sync once any environment issue is fixed

Example fix

// before
if err := doltutil.EnsureCLIRemote(dbPath, "origin", url); err != nil {
	return err // opaque failure when remote already exists
}

// after
if doltutil.FindCLIRemote(dbPath, "origin") != url {
	if err := doltutil.EnsureCLIRemote(dbPath, "origin", url); err != nil {
		return fmt.Errorf("sync remote setup: %w", err)
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("dolt"); err != nil {
	return fmt.Errorf("dolt binary required for CLI remote sync: %w", err)
}
if _, err := os.Stat(filepath.Join(dbPath, ".dolt")); err != nil {
	return fmt.Errorf("%s is not an initialized dolt database", dbPath)
}

Type guard

func isDoltCLIError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "dolt remote add failed:")
}

Try / catch

if err := doltutil.EnsureCLIRemote(dbPath, name, url); err != nil {
	if isDoltCLIError(err) {
		// dolt's combined output is embedded after the prefix — surface it to the user
		return fmt.Errorf("remote setup failed; dolt said: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Running AddCLIRemote/EnsureCLIRemote when: the `dolt` binary is not on PATH; dbPath is not an initialized dolt database (no .dolt directory); a remote with the same name already exists; the dolt version rejects the URL or flags; dbPath is not writable.

Common situations: Running bd sync in a repo where the embedded dolt DB was never initialized; a stale CLI remote left over from a previous sync causing an 'already exists' error; CI containers missing the dolt binary; a dolt upgrade/downgrade changing CLI behavior.

Related errors


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