gastownhall/beads · error

failed to commit pending changes before pull: %w

Error message

failed to commit pending changes before pull: %w

What it means

pullFromPeer tries to auto-commit any pending uncommitted changes before merging from a peer (GH#2474) because Dolt refuses to merge with a dirty working set. If commitBeforePull fails with something other than 'nothing to commit' (isDoltNothingToCommit), the pull aborts with this wrapped error. It signals the local working set couldn't be safely committed, so the merge was not attempted.

Source

Thrown at internal/storage/dolt/federation.go:85

// For git-protocol remotes, uses CLI `dolt pull` to avoid MySQL connection timeouts.
// Returns any merge conflicts if present.
func (s *DoltStore) PullFrom(ctx context.Context, peer string) ([]storage.Conflict, error) {
	var conflicts []storage.Conflict
	err := s.withCircuitWrite(ctx, func(ctx context.Context) error {
		var err error
		conflicts, err = s.pullFromPeer(ctx, peer)
		return err
	})
	return conflicts, err
}

func (s *DoltStore) pullFromPeer(ctx context.Context, peer string) ([]storage.Conflict, error) {
	// GH#2474: Auto-commit pending changes before pull to prevent
	// "cannot merge with uncommitted changes" errors.
	if !s.readOnly {
		if err := s.commitBeforePull(ctx, "auto-commit before pull"); err != nil {
			if !isDoltNothingToCommit(err) {
				return nil, fmt.Errorf("failed to commit pending changes before pull: %w", err)
			}
		}
	}

	// bd-6dnrw.3: pre-pull HEAD for the post-merge is_blocked recompute; an
	// unreadable HEAD degrades to a full recompute.
	preHead := ""
	if !s.readOnly {
		if h, err := s.GetCurrentCommit(ctx); err == nil {
			preHead = h
		}
	}

	// bd-578h9.3: every peer-pull route funnels through the same settle
	// machinery as the default-remote pull (pullTransport): the CLI routes
	// through finishCLIPull, the SQL route through pullWithAutoResolve. A bare
	// peer pull used to leave non-convergent merges behind — an FK
	// delete-vs-insert divergence rolls the merge back with nothing in

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the innermost error: if it's a lock/timeout issue, stop other bd processes and retry the pull.
  2. Run `dolt status` (or bd doctor) to see what's uncommitted; resolve or discard the dirty state manually, then retry.
  3. If the auto-commit itself conflicts, commit or stash the changes deliberately before pulling.
  4. Free disk space / restart the Dolt server if the commit failed on resource or server errors, then re-run the sync.

Example fix

// before: ambiguous dirty state blocks every pull
// error: failed to commit pending changes before pull
// after: commit explicitly before syncing
dolt add -A && dolt commit -m "pre-pull auto-commit"
// or discard unintended changes
dolt checkout .
// then retry the peer pull
Defensive patterns

Strategy: validation

Validate before calling

// Shell: ensure clean working set before peer pull
dolt status --porcelain | grep -q . && { echo "uncommitted changes; commit first"; exit 1; }

Type guard

func IsPrePullCommitError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "failed to commit pending changes before pull")
}

Try / catch

conflicts, err := sync.PullFromPeer(ctx, peer)
if err != nil && strings.Contains(err.Error(), "failed to commit pending changes before pull") {
	// recover: commit or discard dirty state, then retry once
	return sync.CommitAndRetryPull(ctx, peer)
}

Prevention

When it happens

Trigger: Calling pullFromPeer (peer sync flows) with s.readOnly == false while the Dolt working set has changes that commitBeforePull cannot commit — e.g. merge conflicts during the auto-commit, a locked/failed Dolt transaction, or an exec failure in the commit step that isn't a nothing-to-commit condition.

Common situations: Two bd processes writing concurrently so the working set changes between check and commit; a Dolt server error (lock timeout, disk full) blocks the auto-commit; database left in a dirty state by a previously crashed operation.

Related errors


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