gastownhall/beads · error
dolt remote add failed
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.
Solutions
- Read the %s portion of the error message — it contains dolt's own diagnostic output for the failure
- Verify `dolt` is installed and on PATH (`dolt version` succeeds)
- Confirm dbPath holds an initialized dolt database (`dolt init` in dbPath if needed)
- Run `dolt remote -v` in dbPath; if the remote already exists, remove it or let the idempotent EnsureCLIRemote reconcile it
- 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
- Ensure the dolt binary is installed and on PATH in every environment that runs bd sync
- Initialize the dolt database (bd init / dolt init) before configuring remotes
- Use the idempotent EnsureCLIRemote instead of calling AddCLIRemote directly so an existing remote is reconciled, not duplicated
- Pin a known-good dolt version in CI to avoid CLI behavior changes
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
- dolt remote remove failed
- dolt remote -v failed
- bd
- peer remote uses git protocol and requires CLI routing
- add remote
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0b9ab7662d58d765.
Report an issue: GitHub.
Appendix: 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)