gastownhall/beads · error
dolt push failed: %w Output: %s
Error message
dolt push failed: %w Output: %s
What it means
Push() shells out to `dolt push origin main` inside the cached clone and wraps the command's error plus its combined stdout/stderr output. This means dolt itself rejected the push — the local clone could not be pushed to the remote. The wrapped Output text carries dolt's own diagnostic (auth failure, non-fast-forward, network error, etc.).
Source
Thrown at internal/remotecache/cache.go:151
return entry, nil
}
// Push pushes local commits in the cached clone back to the remote.
func (c *Cache) Push(ctx context.Context, remoteURL string) error {
target := c.cloneTarget(remoteURL)
if !c.doltExists(target) {
return fmt.Errorf("no cached clone for %s", remoteURL)
}
lock, err := c.acquireLock(ctx, remoteURL)
if err != nil {
return fmt.Errorf("failed to acquire cache lock: %w", err)
}
defer c.releaseLock(lock)
cmd := doltCmd(ctx, target, "push", "origin", "main")
if output, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("dolt push failed: %w\nOutput: %s", err, output)
}
// Update push timestamp
meta := c.readMeta(remoteURL)
meta.LastPush = time.Now().UnixNano()
c.writeMeta(remoteURL, meta)
return nil
}
// OpenStore opens a DoltStorage from the cached clone using the provided
// StoreOpener. The cache entry directory is used as the beads directory.
// The caller is responsible for calling Close() on the returned store.
//
// Note: OpenStore does not acquire a cache lock. The caller must ensure
// no concurrent Ensure() or Push() is running against the same remoteURL,
// as those modify the underlying dolt database. This is safe for single-
// process CLI use but not for concurrent multi-process access.View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped `Output:` section — dolt's message identifies the actual cause (auth, non-fast-forward, network).
- If non-fast-forward: run Ensure() first to pull, merge fast-forward, then Push().
- Refresh credentials: set DOLT_REMOTE_USER/DOLT_REMOTE_PASSWORD or run `dolt creds use`/`dolt login`.
- Verify the remote is reachable and correct: `dolt ls-remote <url>` or check the URL in your bd config.
- If the clone is corrupted, `Evict(remoteURL)` and Ensure() to re-clone.
Example fix
// before: push without ensuring the clone is fresh
if err := cache.Push(ctx, remoteURL); err != nil { return err }
// after: pull first, then push
if _, err := cache.Ensure(ctx, remoteURL); err != nil { return err }
if err := cache.Push(ctx, remoteURL); err != nil { return err } Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := exec.LookPath("dolt"); err != nil {
return fmt.Errorf("dolt CLI required")
}
if err := remotecache.ValidateRemoteURL(remoteURL); err != nil {
return err
} Try / catch
if err := cache.Push(ctx, url); err != nil {
var doltOutput string
if i := strings.Index(err.Error(), "Output:"); i >= 0 {
doltOutput = err.Error()[i:]
}
switch {
case strings.Contains(doltOutput, "unexpected client error: unauthorized"),
strings.Contains(doltOutput, "authentication"):
return fmt.Errorf("refresh dolt credentials (DOLT_REMOTE_USER/DOLT_REMOTE_PASSWORD or dolt creds): %w", err)
case strings.Contains(doltOutput, "Non-Fast-Forward"):
if _, err := cache.Ensure(ctx, url); err != nil { return err }
return cache.Push(ctx, url)
}
return err
} Prevention
- Always Ensure() (pull) before Push() to avoid non-fast-forward rejections.
- Keep Dolt credentials current (dolt creds / env vars); check expiry in CI.
- Verify remote reachability (VPN/proxy) before long sync batches.
- Check dolt's wrapped Output text first — it names the real cause.
When it happens
Trigger: Cache.Push(ctx, remoteURL) runs dolt push and it exits non-zero: remote is ahead (non-fast-forward), missing/invalid credentials (DOLT_REMOTE_USER/DOLT_REMOTE_PASSWORD/dolt creds), unreachable remote, remote branch protection, or a corrupted local clone.
Common situations: Expired Dolthub credentials; pushing without pulling first so origin/main has commits the clone lacks; offline or VPN-required networks; remote repo deleted or renamed; wrong URL typed in config.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c86b6996d5de5b3e.
Report an issue: GitHub.