gastownhall/beads · error

delete remote-tracking ref %s: %w

Error message

delete remote-tracking ref %s: %w

What it means

PruneRemoteRefs deletes each cached remote-tracking ref via CALL DOLT_BRANCH('-D', '-r', name). This error wraps a failure of that stored-procedure call for a specific ref, with the ref name embedded in the message. It reports which ref could not be deleted; the returned slice contains the refs already deleted before the failure.

Source

Thrown at internal/storage/versioncontrolops/remoterefs.go:44

}

// PruneRemoteRefs deletes every cached remote-tracking ref and returns the
// names deleted. After a history squash (Flatten/Compact) these refs still
// anchor the pre-squash commit chain, so DOLT_GC treats the entire old history
// as reachable and reclaims nothing (bd-agctw). Pruning is safe on a squashed
// workspace: the refs are local caches only — nothing is deleted on the remote
// itself — and the next push or fetch re-creates them at the new tip.
//
// On error, the returned slice holds the refs deleted before the failure.
func PruneRemoteRefs(ctx context.Context, db DBConn) ([]string, error) {
	refs, err := ListRemoteRefs(ctx, db)
	if err != nil {
		return nil, err
	}
	var pruned []string
	for _, name := range refs {
		if _, err := db.ExecContext(ctx, "CALL DOLT_BRANCH('-D', '-r', ?)", name); err != nil {
			return pruned, fmt.Errorf("delete remote-tracking ref %s: %w", name, err)
		}
		pruned = append(pruned, name)
	}
	return pruned, nil
}

// ListTags returns the names of all Dolt tags, sorted by name. Tags anchor
// history the same way remote-tracking refs do, but they are user-created, so
// callers should surface them rather than delete them.
func ListTags(ctx context.Context, db DBConn) ([]string, error) {
	rows, err := db.QueryContext(ctx, "SELECT tag_name FROM dolt_tags ORDER BY tag_name")
	if err != nil {
		return nil, fmt.Errorf("list tags: %w", err)
	}
	defer rows.Close()

	var tags []string
	for rows.Next() {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the ref name in the error message and check whether it still exists (SELECT name FROM dolt_remote_branches); refs deleted concurrently can simply be skipped and the call retried.
  2. Retry PruneRemoteRefs — it is idempotent per ref and the error tells you where to resume (refs before it were already pruned).
  3. If the context was cancelled, re-run with a fresh context; already-deleted refs will not error on a second pass.
  4. Check Dolt engine logs for the underlying DOLT_BRANCH failure if retries keep failing (permissions, read-only mode, or engine bug).

Example fix

// before
pruned, err := versioncontrolops.PruneRemoteRefs(ctx, db)
if err != nil { return err } // treats partial success as total failure
// after: handle partial results and retry remaining refs
pruned, err := versioncontrolops.PruneRemoteRefs(ctx, db)
if err != nil {
    log.Printf("pruned %d refs before failure: %v", len(pruned), err)
    // retry is safe: remaining refs are still listed and deleted
    _, err = versioncontrolops.PruneRemoteRefs(ctx, db)
}
Defensive patterns

Strategy: retry

Validate before calling

rows, err := db.QueryContext(ctx, "SELECT name FROM dolt_remote_branches ORDER BY name")
if err != nil {
    return err
}
// snapshot refs immediately before pruning to reduce concurrent-modification risk

Try / catch

pruned, err := versioncontrolops.PruneRemoteRefs(ctx, db)
if err != nil {
    // pruned holds refs deleted before the failure; retry is safe and resumes where it stopped
    log.Printf("partial prune (%d done): %v", len(pruned), err)
    time.Sleep(retryDelay)
    _, err = versioncontrolops.PruneRemoteRefs(ctx, db)
}

Prevention

When it happens

Trigger: Calling PruneRemoteRefs when CALL DOLT_BRANCH('-D', '-r', ?) fails for a ref: the ref vanished concurrently, the Dolt engine rejects the delete, the connection breaks mid-loop, or the context is cancelled partway through the batch.

Common situations: Another process fetched/pushed and removed or recreated the ref while pruning; Dolt server-side constraint or permission error on DOLT_BRANCH; network drop or timeout during a long pruning loop; embedded Dolt refusing the call in a read-only session.

Related errors


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