gastownhall/beads · error
compare local HEAD to %s: %w
Error message
compare local HEAD to %s: %w
What it means
After validating the ref, LocalIsStrictAncestorOf runs a dolt_log AS OF query comparing the ref's history to local HEAD. If db.QueryRowContext or the row Scan fails (connection error, unknown ref/table error from Dolt, context cancellation), the error is wrapped as "compare local HEAD to <ref>: %w" and the function returns false.
Source
Thrown at internal/storage/versioncontrolops/fastforward.go:46
return false, fmt.Errorf("invalid ref: %w", err)
}
// Dolt's AS OF requires a literal ref, not a bind parameter; ref was
// validated above via the shared allowlist regex, mirroring the same
// ahead/behind pattern used by EmbeddedDoltStore.SyncStatus
// (internal/storage/embeddeddolt/federation.go).
//nolint:gosec // G201: ref validated by ValidateRef above — AS OF requires a literal
query := fmt.Sprintf(`
SELECT
(SELECT COUNT(*) FROM dolt_log WHERE commit_hash NOT IN
(SELECT commit_hash FROM dolt_log AS OF '%s')) AS ahead,
(SELECT COUNT(*) FROM dolt_log AS OF '%s' WHERE commit_hash NOT IN
(SELECT commit_hash FROM dolt_log)) AS behind
`, ref, ref)
var ahead, behind int
if err := db.QueryRowContext(ctx, query).Scan(&ahead, &behind); err != nil {
return false, fmt.Errorf("compare local HEAD to %s: %w", ref, err)
}
return ahead == 0 && behind >= 1, nil
}
// WorkingSetClean reports whether the Dolt working set has no uncommitted
// changes, EXCLUDING dolt-ignored wisp tables ("wisps" and "wisp_*"), which
// cannot be staged/committed and so should never block a clean-working-set
// gate. This mirrors the exclusion in DirtyTableTracker.MarkDirty
// (commit.go), but — unlike the unexported workingSetClean in
// mergesettle.go, which does not exclude wisps and swallows its query
// error — this reports the error to the caller instead of treating it as
// dirty.
func WorkingSetClean(ctx context.Context, db DBConn) (bool, error) {
rows, err := db.QueryContext(ctx, "SELECT table_name FROM dolt_status")
if err != nil {
return false, fmt.Errorf("query dolt_status: %w", err)
}View on GitHub (pinned to 71377f2769)
Solutions
- Verify the ref exists locally (it must be a cached remote-tracking ref, e.g. after a fetch) — the function performs no fetch of its own.
- Run CALL DOLT_FETCH('origin') or the repo's sync step, then retry.
- Check the underlying wrapped error: sql.ErrNoRows/context.DeadlineExceeded indicate DB or context issues, not a ref problem.
- Confirm the Dolt server/embedded engine is running and dolt_log is queryable.
Example fix
// before
ok, err := versioncontrolops.LocalIsStrictAncestorOf(ctx, db, "origin/main")
// after
if err := fetchRemoteRefs(ctx); err != nil { // ensures origin/* refs are cached
return err
}
ok, err := versioncontrolops.LocalIsStrictAncestorOf(ctx, db, "origin/main") Defensive patterns
Strategy: try-catch
Validate before calling
var exists int
err := db.QueryRowContext(ctx,
"SELECT COUNT(*) FROM dolt_branch WHERE name = ?", ref).Scan(&exists)
if err != nil || exists == 0 {
return fmt.Errorf("ref %q not cached locally; fetch first", ref)
} Try / catch
ok, err := versioncontrolops.LocalIsStrictAncestorOf(ctx, db, ref)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return retryWithNewDeadline(ctx)
}
return fmt.Errorf("ancestor check for %s failed: %w", ref, err)
} Prevention
- Fetch remote refs before any ancestor check — the function performs no fetch of its own.
- Wrap calls with a reasonable context timeout so transient DB hangs don't stall callers.
- Verify ref spelling against `CALL DOLT_BRANCH()` output when debugging.
When it happens
Trigger: Querying with a ref that passes syntax validation but does not exist in the database (AS OF 'origin/main' when that ref was never fetched); a closed/failed DB connection; the context being cancelled mid-query; dolt_log being unreadable.
Common situations: Calling before any fetch so the remote-tracking ref is absent; typo'd branch name like 'orgin/main'; network/database outage while the embedded Dolt engine is unavailable; operation cancelled by a deadline.
Related errors
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to query orphaned dependencies: %w
- row iteration error: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/729c53c1693f9dad.
Report an issue: GitHub.