gastownhall/beads · error

fetch from %s/%s: %w

Error message

fetch from %s/%s: %w

What it means

PullWithStrategy wraps a failed DOLT_FETCH step (CALL DOLT_FETCH([--user], remote, branch)) as "fetch from <remote>/<branch>: <underlying>". The library throws it because the pull is split into an explicit fetch (to avoid a Dolt embedded-mode panic on unconfigured upstream tracking, GH#3144) followed by a local merge; this error identifies the network/fetch half of that split. Any fetch failure — remote not found, auth failure, unreachable peer, unknown branch — surfaces here before merging is attempted.

Source

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

	return PullWithStrategy(ctx, db, remote, branch, user, "")
}

// PullWithStrategy is Pull with the #4992 part 2 operator escape hatch:
// conflicts TryAutoResolveMergeConflicts declines are, when strategy is
// non-empty, resolved with strategy ("ours" or "theirs") instead of aborting
// the pull for the operator to resolve out-of-band. strategy == "" is exactly
// Pull's behavior. See MergeAndSettleWithStrategy/SettleMerge for the
// resolution logic.
func PullWithStrategy(ctx context.Context, db DBConn, remote, branch, user, strategy string) error {
	if err := withRemoteEnvGuards(func() error {
		if user != "" {
			_, err := db.ExecContext(ctx, "CALL DOLT_FETCH('--user', ?, ?, ?)", user, remote, branch)
			return err
		}
		_, err := db.ExecContext(ctx, "CALL DOLT_FETCH(?, ?)", remote, branch)
		return err
	}); err != nil {
		return fmt.Errorf("fetch from %s/%s: %w", remote, branch, err)
	}
	trackingRef := remote + "/" + branch
	if err := MergeAndSettleWithStrategy(ctx, db, trackingRef, strategy); err != nil {
		return fmt.Errorf("merge %s: %w", trackingRef, err)
	}
	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the remote name against dolt_remotes (bd vc remote list) and confirm the branch exists on the remote.
  2. Set DOLT_REMOTE_PASSWORD in the server environment or pass the correct user to authenticate.
  3. Fix the wrapped network error (connectivity, DNS, TLS) and retry the pull.
  4. If the branch was deleted upstream, create it on the remote or stop pulling it.

Example fix

// before
err := versioncontrolops.Pull(ctx, db, "orgin", "main", "") // typo'd remote
// after
err := versioncontrolops.Pull(ctx, db, "origin", "main", "") // after adding remote 'origin' and setting DOLT_REMOTE_PASSWORD
Defensive patterns

Strategy: retry

Validate before calling

remotes, err := versioncontrolops.ListRemotes(ctx, db)
if err != nil { return err }
valid := false
for _, r := range remotes {
    if r.Name == remote { valid = true }
}
if !valid { return fmt.Errorf("remote %q not found; add it first", remote) }
if user != "" && os.Getenv("DOLT_REMOTE_PASSWORD") == "" {
    return fmt.Errorf("DOLT_REMOTE_PASSWORD must be set for user %q", user)
}

Try / catch

err := versioncontrolops.Pull(ctx, db, remote, branch, user)
if err != nil && strings.HasPrefix(err.Error(), "fetch from ") {
    if isTransientNetErr(err) {
        time.Sleep(backoff)
        err = versioncontrolops.Pull(ctx, db, remote, branch, user)
    }
    if err != nil { return fmt.Errorf("pull aborted at fetch step: %w", err) }
}

Prevention

When it happens

Trigger: Calling Pull or PullWithStrategy when the remote is unconfigured or misspelled; the branch does not exist on the remote; --user is given but DOLT_REMOTE_PASSWORD is missing/wrong in the server env; the peer is unreachable over the network.

Common situations: First sync against a remote added with a different name; expired or rotated remote credentials; offline laptop / DNS failure; pulling a branch the peer deleted.

Related errors


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