gastownhall/beads · error

push: %w

Error message

push: %w

What it means

The push step of the sync loop failed with an error that is not a push race (remote moved fast-forwardably between merge and push — those retry). All other push errors abort the sync loop.

Source

Thrown at cmd/bd/sync.go:398

		// exhaustion from inheriting stuck-looking evidence.
		evidence = dirtyEvidence{}
		out.RowsCorrected += corrected

		// From here on this run has completed a pull and an is_blocked repair,
		// so a conflict on a LATER attempt cannot describe itself as a run that
		// touched nothing.
		out.Pulled = true

		ops.report("push")
		pushErr := ops.push(ctx)
		if pushErr == nil {
			out.Status = syncStatusOK
			out.Pushed = true
			out.LastPushError = ""
			return out, nil
		}
		if !isPushRaceErr(pushErr) {
			return out, fmt.Errorf("push: %w", pushErr)
		}
		// Another replica pushed between our merge and our push, so the remote
		// genuinely moved: loop back to pull and pick up its commits. Anything
		// that is not a fast-forward race cannot converge by retrying and was
		// returned above.
		out.LastPushError = pushErr.Error()
		out.Transients = append(out.Transients, syncTransient{
			Attempt: attempt, Kind: syncTransientPushRace, Error: pushErr.Error(),
		})
		ops.report("push race (non-fast-forward) — re-pulling and retrying")
	}

	out.Status = syncStatusRetriesExhausted
	out.DirtyGraphFingerprint = evidence.fold()
	return out, nil
}

// dirtyEvidence accumulates one fingerprint per blocked attempt.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped pushErr for the concrete rejection reason
  2. Refresh remote credentials/token
  3. Fetch and reconcile with the remote (bd sync pull path or dolt pull) if history diverged non-fast-forwardably
  4. Verify the remote is writable and healthy (server logs, quotas)
Defensive patterns

Strategy: retry

Validate before calling

// verify remote is writable and credentials valid before syncing
if err := checkRemoteWritable(remoteURL); err != nil {
    return fmt.Errorf("remote not writable: %w", err)
}

Try / catch

out, err := runSyncCommand(ctx, opts)
if err != nil {
    var pushErr *PushError
    if errors.As(err, &pushErr) && !isPushRaceErr(pushErr.Unwrap()) {
        // non-race: inspect auth/permission/divergence, fix, then retry
    }
    return err
}

Prevention

When it happens

Trigger: ops.push returns a non-race error: remote rejects the push (auth, protected refs, non-fast-forward divergence), Dolt push RPC failure, or remote storage unavailable.

Common situations: Expired remote credentials; another replica force-pushed divergent history; remote Dolt server read-only or at capacity; firewall/proxy blocking the push endpoint.

Related errors


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