gastownhall/beads · error

fetch from %s: %w

Error message

fetch from %s: %w

What it means

Fetch runs CALL DOLT_FETCH(?) (or with '--user' when credentials are supplied) to fetch refs from a peer remote without merging. This error wraps any failure of the DOLT_FETCH call: unreachable peer, authentication failure, or a Dolt-internal fetch error. Per the source, a failed DOLT_FETCH can leave orphaned tmp_pack_* files in the git-remote-cache; the embedded store sweeps these on connection teardown, and DOLT_GC must NOT be run as a fix because it invalidates other open sessions (bd-6dnrw.10).

Source

Thrown at internal/storage/versioncontrolops/remotes.go:57

// If user is non-empty, authenticates with that user — DOLT_REMOTE_PASSWORD
// must be set in the in-process Dolt server's environment.
//
// A failed DOLT_FETCH can leave orphaned tmp_pack_* files in the
// git-remote-cache; the embedded store's connection teardown sweeps those
// (cleanGitRemoteCacheGarbage). Do NOT run DOLT_GC here: dolt_gc invalidates
// every other open session on the same engine, so a failed fetch would break
// concurrent in-flight connections (bd-6dnrw.10).
func Fetch(ctx context.Context, db DBConn, peer, user string) error {
	err := withRemoteEnvGuards(func() error {
		if user != "" {
			_, err := db.ExecContext(ctx, "CALL DOLT_FETCH('--user', ?, ?)", user, peer)
			return err
		}
		_, err := db.ExecContext(ctx, "CALL DOLT_FETCH(?)", peer)
		return err
	})
	if err != nil {
		return fmt.Errorf("fetch from %s: %w", peer, err)
	}
	return nil
}

// Push pushes the given branch to the named remote.
// If user is non-empty, authenticates with that user — DOLT_REMOTE_PASSWORD
// must be set in the in-process Dolt server's environment. Required when
// pushing to a remotesapi server that enforces CLONE_ADMIN authentication.
func Push(ctx context.Context, db DBConn, remote, branch, user string) error {
	err := withRemoteEnvGuards(func() error {
		if user != "" {
			_, err := db.ExecContext(ctx, "CALL DOLT_PUSH('--user', ?, ?, ?)", user, remote, branch)
			return err
		}
		_, err := db.ExecContext(ctx, "CALL DOLT_PUSH(?, ?)", remote, branch)
		return err
	})
	if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the peer remote is reachable (curl/ping its URL) and the name is correct
  2. If user is non-empty, ensure DOLT_REMOTE_PASSWORD is set in the Dolt server's environment before the call
  3. Retry the fetch after a transient failure — do NOT run DOLT_GC to clean up (it breaks concurrent sessions); tmp_pack_* garbage is swept on connection teardown
  4. Inspect the wrapped error for the Dolt fetch message (auth vs network vs unknown remote)
  5. Check TLS/certificate configuration if the peer uses HTTPS

Example fix

// before
if err := versioncontrolops.Fetch(ctx, db, peer, user); err != nil {
	return err
}
// after
if err := versioncontrolops.Fetch(ctx, db, peer, user); err != nil {
	var netErr net.Error
	if errors.As(err, &netErr) && netErr.Timeout() {
		return versioncontrolops.Fetch(ctx, db, peer, user) // retry transient
	}
	return fmt.Errorf("fetch from %s: %w", peer, err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Verify the peer is configured and the auth env is present before fetching
remotes, err := versioncontrolops.ListRemotes(ctx, db)
if err != nil {
	return err
}
peerOK := false
for _, r := range remotes {
	if r.Name == peer {
		peerOK = true
	}
}
if !peerOK {
	return fmt.Errorf("peer %q not configured", peer)
}
if user != "" && os.Getenv("DOLT_REMOTE_PASSWORD") == "" {
	return fmt.Errorf("DOLT_REMOTE_PASSWORD must be set in the Dolt server env for user auth")
}

Type guard

func isTransientFetchErr(err error) bool {
	var netErr net.Error
	return errors.As(err, &netErr) && netErr.Timeout()
}

Try / catch

err := versioncontrolops.Fetch(ctx, db, peer, user)
for i := 0; err != nil && i < 3 && isTransientFetchErr(err); i++ {
	time.Sleep(time.Second << i)
	err = versioncontrolops.Fetch(ctx, db, peer, user)
}
if err != nil {
	return fmt.Errorf("fetch from %s: %w", peer, err)
}

Prevention

When it happens

Trigger: Calling Fetch(ctx, db, peer, user) where the peer remote URL is unreachable, credentials are wrong or DOLT_REMOTE_PASSWORD is unset when user is non-empty, the remote rejects the fetch, or ExecContext fails (connection/context error).

Common situations: Peer server down or wrong URL; missing DOLT_REMOTE_PASSWORD in the in-process Dolt server environment when authenticating; network/firewall blocking the peer; SSL/TLS mismatch; transient network blips during large fetches.

Related errors


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