gastownhall/beads · error
--strategy %s contradicts --%s
Error message
--strategy %s contradicts --%s
What it means
resolveStrategy in cmd/bd/conflicts.go builds a single conflict-resolution strategy from multiple flags: --ours and --theirs map directly to versioncontrolops.ConflictStrategyOurs/Theirs, and --strategy <name> is a generic override. If --strategy is set but contradicts the strategy implied by --ours/--theirs, the function refuses to guess and returns this error. It exists to make flag conflicts explicit rather than silently letting the last flag win.
Source
Thrown at cmd/bd/conflicts.go:672
total += t.Count
}
return total, nil
}
// resolveStrategy reads the strategy from --ours/--theirs/--strategy.
func resolveStrategy() (string, error) {
picked := ""
switch {
case conflictsResolveOurs && conflictsResolveTheirs:
return "", fmt.Errorf("pass --ours or --theirs, not both")
case conflictsResolveOurs:
picked = versioncontrolops.ConflictStrategyOurs
case conflictsResolveTheirs:
picked = versioncontrolops.ConflictStrategyTheirs
}
if conflictsResolveStrat != "" {
if picked != "" && picked != conflictsResolveStrat {
return "", fmt.Errorf("--strategy %s contradicts --%s", conflictsResolveStrat, picked)
}
picked = conflictsResolveStrat
}
if picked == "" {
return "", fmt.Errorf("a resolution strategy is required: --ours or --theirs")
}
if err := versioncontrolops.ValidateConflictStrategy(picked); err != nil {
return "", err
}
return picked, nil
}
// filterShownFields drops the agreeing fields from JSON output unless the
// caller asked for all of them, so a conflict reads as its handful of
// diverged fields rather than the whole row.
func filterShownFields(rows []storage.ConflictRow, allFields bool) []storage.ConflictRow {
if allFields {
return rowsView on GitHub (pinned to 71377f2769)
Solutions
- Remove either --strategy or the --ours/--theirs flag so only one mechanism specifies the strategy
- Pass the same value to both forms if your tooling requires both (e.g. --theirs --strategy theirs)
- Use only --strategy <ours|theirs> as the canonical form going forward
Example fix
// before bd conflicts resolve --theirs --strategy ours // after bd conflicts resolve --strategy theirs
Defensive patterns
Strategy: validation
Validate before calling
// validate flags before running bd
ours=""; theirs=""; strat=""
# ... parse flags ...
if [ -n "$strat" ] && { [ -n "$ours" ] || [ -n "$theirs" ]; }; then
implied=$([ -n "$ours" ] && echo ours || echo theirs)
[ "$strat" = "$implied" ] || { echo "--strategy $strat contradicts --$implied" >&2; exit 2; }
fi Try / catch
if err := resolveStrategy(); err != nil {
if strings.Contains(err.Error(), "contradicts") {
// surface flag-conflict guidance to the user
}
return err
} Prevention
- Use only --strategy as the canonical mechanism in scripts
- Never combine --ours/--theirs with --strategy in one invocation
- Wrap bd calls in a helper that asserts mutually exclusive flags
When it happens
Trigger: Calling `bd conflicts resolve` with --strategy ours (or theirs) while also passing the opposite explicit flag, e.g. `bd conflicts resolve --theirs --strategy ours`: picked becomes ConflictStrategyTheirs from --theirs, then conflictsResolveStrat ("ours") differs and the error fires.
Common situations: Shell scripts or aliases that hardcode --strategy while a user adds --ours/--theirs on top; documentation drift where older invocations used --ours/--theirs and newer automation uses --strategy; copy-pasted commands combining both spellings.
Related errors
- %w (--prefer-local, --prefer-ado, --prefer-newer)
- cannot use multiple conflict resolution flags
- cannot use both --pull-only and --push-only
- a resolution strategy is required: --ours or --theirs
- --server and --proxied-server are mutually exclusive
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c13a1f99e92e0098.
Report an issue: GitHub.