{"record":{"id":"522694edf02171fe","repo":"gastownhall/beads","slug":"merge-s-w","errorCode":null,"errorMessage":"merge %s: %w","messagePattern":"merge (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/remotes.go","lineNumber":131,"sourceCode":"// conflicts TryAutoResolveMergeConflicts declines are, when strategy is\n// non-empty, resolved with strategy (\"ours\" or \"theirs\") instead of aborting\n// the pull for the operator to resolve out-of-band. strategy == \"\" is exactly\n// Pull's behavior. See MergeAndSettleWithStrategy/SettleMerge for the\n// resolution logic.\nfunc PullWithStrategy(ctx context.Context, db DBConn, remote, branch, user, strategy string) error {\n\tif err := withRemoteEnvGuards(func() error {\n\t\tif user != \"\" {\n\t\t\t_, err := db.ExecContext(ctx, \"CALL DOLT_FETCH('--user', ?, ?, ?)\", user, remote, branch)\n\t\t\treturn err\n\t\t}\n\t\t_, err := db.ExecContext(ctx, \"CALL DOLT_FETCH(?, ?)\", remote, branch)\n\t\treturn err\n\t}); err != nil {\n\t\treturn fmt.Errorf(\"fetch from %s/%s: %w\", remote, branch, err)\n\t}\n\ttrackingRef := remote + \"/\" + branch\n\tif err := MergeAndSettleWithStrategy(ctx, db, trackingRef, strategy); err != nil {\n\t\treturn fmt.Errorf(\"merge %s: %w\", trackingRef, err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":113,"sourceCodeEnd":135,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/remotes.go#L113-L135","documentation":"PullWithStrategy wraps a failed merge of the freshly fetched tracking ref (<remote>/<branch>) as \"merge <ref>: <underlying>\". After DOLT_FETCH succeeds, the tracking ref is merged via MergeAndSettleWithStrategy, which auto-resolves safe conflict classes and repairs FK cascades; this error means the merge step itself failed — either an unresolved conflict or a settle-step failure. It is distinct from 4261: the fetch already succeeded, so only the local merge is at fault.","triggerScenarios":"Pull/PullWithStrategy when the local and remote branch histories conflict in a way TryAutoResolveMergeConflicts declines and strategy is empty; the merged data violates foreign keys that cannot be repaired; the session is not a single session (MergeAndSettle requires a pinned single-session db); the working set is dirty in a way that blocks the merge.","commonSituations":"Two machines edited the same issue rows while offline; concurrent uncommitted writes on other connections during the pull; operator chose a pull where a --strategy ours|theirs resolution was needed.","solutions":["Retry the pull with a strategy: use the PullWithStrategy variant (or bd vc pull --strategy ours|theirs) to force-resolve declined conflicts.","Commit or clear local working-set changes before pulling so the merge has a clean base.","Ensure the db passed is a single (pinned) session as MergeAndSettle requires.","Read the wrapped error: for FK violations repair the conflicting rows, then re-run the pull."],"exampleFix":"// before\nerr := versioncontrolops.Pull(ctx, db, \"origin\", \"main\", \"\") // conflict aborts pull\n// after\nerr := versioncontrolops.PullWithStrategy(ctx, db, \"origin\", \"main\", \"\", \"theirs\") // accept remote rows on conflict","handlingStrategy":"fallback","validationCode":"st, err := versioncontrolops.Status(ctx, db)\nif err != nil { return err }\nif len(st.Staged) > 0 || len(st.Unstaged) > 0 {\n    return fmt.Errorf(\"commit or clear working-set changes before pulling\")\n}","typeGuard":"func isMergeStepErr(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"merge \")\n}","tryCatchPattern":"err := versioncontrolops.Pull(ctx, db, remote, branch, user)\nif isMergeStepErr(err) {\n    // fall back to operator-chosen resolution\n    err = versioncontrolops.PullWithStrategy(ctx, db, remote, branch, user, \"theirs\")\n    if err != nil { return fmt.Errorf(\"pull failed even with strategy: %w\", err) }\n}","preventionTips":["Pull through a single pinned db session as MergeAndSettle requires; don't share the handle across connections mid-pull.","Commit local work before pulling so merges start from a clean base.","Prefer PullWithStrategy with an explicit ours/theirs policy in unattended automation.","Pull frequently to keep divergence (and conflict surface) small."],"tags":["git","dolt","merge","conflict","pull"],"backgroundTag":"merge-conflict","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}