gastownhall/beads · error

failed to add remote %s: %w

Error message

failed to add remote %s: %w

What it means

AddRemote runs CALL DOLT_REMOTE('add', ?, ?) to register a named remote with a URL. This error wraps a failure of that stored-procedure call. Dolt rejects the operation if the remote name already exists, the URL is malformed/unsupported, or the procedure fails at the storage layer (read-only database, non-Dolt database, server error).

Source

Thrown at internal/storage/dolt/store.go:4997

}

// HasRemote checks if a Dolt remote with the given name exists.
func (s *DoltStore) HasRemote(ctx context.Context, name string) (bool, error) {
	var count int
	err := s.queryRowContext(ctx, func(row *sql.Row) error {
		return row.Scan(&count)
	}, "SELECT COUNT(*) FROM dolt_remotes WHERE name = ?", name)
	if err != nil {
		return false, fmt.Errorf("failed to check remote %s: %w", name, err)
	}
	return count > 0, nil
}

// AddRemote adds a Dolt remote
func (s *DoltStore) AddRemote(ctx context.Context, name, url string) error {
	_, err := s.db.ExecContext(ctx, "CALL DOLT_REMOTE('add', ?, ?)", name, url)
	if err != nil {
		return fmt.Errorf("failed to add remote %s: %w", name, err)
	}
	return nil
}

// Status returns the current Dolt status (staged/unstaged changes)
func (s *DoltStore) Status(ctx context.Context) (*DoltStatus, error) {
	return versioncontrolops.Status(ctx, s.db)
}

// DoltStatus is an alias for storage.Status.
type DoltStatus = storage.Status

// StatusEntry is an alias for storage.StatusEntry.
type StatusEntry = storage.StatusEntry

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check for an existing remote first (HasRemote) and skip/update instead of re-adding.
  2. Validate the URL format (local path, http(s), aws://, or gs://) before calling.
  3. Run `dolt remotes list` / SELECT * FROM dolt_remotes to inspect current remotes and the exact server error.
  4. Ensure the database is writable and is a Dolt database.
  5. Verify credentials/config for cloud remotes (AWS/GCS) are present on the server.

Example fix

// before
if err := store.AddRemote(ctx, "origin", url); err != nil { return err }
// after
exists, err := store.HasRemote(ctx, "origin")
if err != nil { return err }
if !exists {
    if err := store.AddRemote(ctx, "origin", url); err != nil { return err }
}
Defensive patterns

Strategy: validation

Validate before calling

var validRemoteURL = regexp.MustCompile(`^(https?://|aws://|gs://|/[\w./-])`)
if !validRemoteURL.MatchString(url) { return fmt.Errorf("invalid remote URL: %s", url) }
exists, err := store.HasRemote(ctx, name)
if err == nil && exists { return fmt.Errorf("remote %q already exists", name) }

Try / catch

err := store.AddRemote(ctx, name, url)
if err != nil {
    if exists, _ := store.HasRemote(ctx, name); exists {
        return nil // idempotent: remote already added
    }
    return fmt.Errorf("add remote %q: %w", name, err)
}

Prevention

When it happens

Trigger: Calling AddRemote(ctx, name, url) where DOLT_REMOTE('add',...) errors: duplicate remote name, invalid URL scheme (not a file path, gs://, aws://, or http(s) URL), read-only connection, or executing against a non-Dolt backend.

Common situations: Re-running setup scripts that re-add an existing 'origin'; typos in remote URLs (missing scheme or path); pointing at cloud remotes without credentials/config; running inside a read-only replica.

Related errors


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