gastownhall/beads · error
fast-forward to %s: %w
Error message
fast-forward to %s: %w
What it means
FastForwardAdopt executes CALL DOLT_MERGE('--ff-only', ?) after validating the ref. If the merge fails — the ref doesn't exist locally, the merge would not be a pure fast-forward, uncommitted changes block the merge, or a Dolt error occurs — the error is wrapped as "fast-forward to <ref>: %w".
Source
Thrown at internal/storage/versioncontrolops/fastforward.go:95
}
if err := rows.Err(); err != nil {
return false, fmt.Errorf("iterate dolt_status: %w", err)
}
return clean, nil
}
// FastForwardAdopt fast-forwards the current branch to ref via
// CALL DOLT_MERGE('--ff-only', ref). ref must already be cached locally
// (e.g. a remote-tracking ref updated by a prior fetch); this performs no
// fetch of its own and fails if the merge would not be a pure fast-forward.
func FastForwardAdopt(ctx context.Context, db DBConn, ref string) error {
if err := issueops.ValidateRef(ref); err != nil {
return fmt.Errorf("invalid ref: %w", err)
}
if _, err := db.ExecContext(ctx, "CALL DOLT_MERGE('--ff-only', ?)", ref); err != nil {
return fmt.Errorf("fast-forward to %s: %w", ref, err)
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Fetch first (CALL DOLT_FETCH('origin')) — FastForwardAdopt performs no fetch of its own.
- Check WorkingSetClean and commit or stash uncommitted changes before the merge.
- If the branch has diverged, decide whether to rebase locally or use a non-ff strategy; --ff-only will not overwrite local commits.
- Read the wrapped Dolt error message — it names the merge conflict or unknown-ref cause.
Example fix
// before
versioncontrolops.FastForwardAdopt(ctx, db, "origin/main")
// after
if err := fetchOrigin(ctx, db); err != nil { return err } // ensure ref is cached
clean, err := versioncontrolops.WorkingSetClean(ctx, db)
if err != nil || !clean { return fmt.Errorf("working set dirty, aborting ff") }
versioncontrolops.FastForwardAdopt(ctx, db, "origin/main") Defensive patterns
Strategy: validation
Validate before calling
// fetch + preconditions before FastForwardAdopt
if err := fetchOrigin(ctx, db); err != nil { return err } // CALL DOLT_FETCH('origin')
clean, err := versioncontrolops.WorkingSetClean(ctx, db)
if err != nil { return err }
if !clean { return fmt.Errorf("uncommitted changes block --ff-only merge") } Try / catch
err := versioncontrolops.FastForwardAdopt(ctx, db, "origin/main")
if err != nil {
if strings.Contains(err.Error(), "not a fast-forward") || strings.Contains(err.Error(), "diverged") {
return fmt.Errorf("branch diverged; rebase or merge manually")
}
return err
} Prevention
- Always fetch before adopting — FastForwardAdopt does no fetch of its own.
- Check WorkingSetClean immediately before the merge.
- Treat --ff-only failures as a signal of divergence; never force it.
- Be cautious when an upstream was force-pushed — history rewrites always fail here.
When it happens
Trigger: Calling FastForwardAdopt with a valid-syntax ref that was never fetched (unknown ref); local branch has commits not on ref (non-fast-forward); dirty working set; detached or unexpected current branch; concurrent Dolt session state conflict.
Common situations: Skipping the fetch step the docs require; local work diverged from origin/main so --ff-only refuses; uncommitted dolt_status entries; running against a branch whose upstream was force-pushed and rewrote history.
Related errors
- merge %s: %w
- merge branch %s: %w (resolve with: bd vc merge %s --strategy
- merge branch %s: %w
- failed to commit pending changes before pull: %w
- merge failed: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/85aea4d8c0c7fa77.
Report an issue: GitHub.