{"record":{"id":"afcfdb6d7bff1c74","repo":"gastownhall/beads","slug":"conflict-for-s-s-was-not-cleared-no-conflict-ro","errorCode":null,"errorMessage":"conflict for %s %s was not cleared (no conflict row deleted)","messagePattern":"conflict for (.+?) (.+?) was not cleared \\(no conflict row deleted\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/versioncontrolops/conflicts.go","lineNumber":435,"sourceCode":"\t\t// only when the row really is gone.\n\t\tif n, err := res.RowsAffected(); err != nil || n == 0 {\n\t\t\tpresent, err := conflictTargetStillPresent(ctx, db, table, keyCol, ourKey)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"confirm %s %s still exists after writing their values: %w\", table, key, err)\n\t\t\t}\n\t\t\tif !present {\n\t\t\t\treturn fmt.Errorf(\"their values for %s %s matched no row (was it deleted concurrently?); conflict left unresolved\", table, key)\n\t\t\t}\n\t\t}\n\t}\n\n\tdel := fmt.Sprintf(\"DELETE FROM `dolt_conflicts_%s` WHERE `our_%s` = ?\", table, keyCol) //nolint:gosec // identifiers validated\n\tres, err := db.ExecContext(ctx, del, ourKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"clear conflict for %s %s: %w\", table, key, err)\n\t}\n\tif n, err := res.RowsAffected(); err == nil && n == 0 {\n\t\treturn fmt.Errorf(\"conflict for %s %s was not cleared (no conflict row deleted)\", table, key)\n\t}\n\treturn nil\n}\n\n// GetMergeBlockers reports the merge state that `bd conflicts` cannot show as\n// rows: whether a merge is open at all, plus the schema conflicts and\n// constraint violations that make dolt refuse the merge commit even when\n// every dolt_conflicts row is resolved (wy-36ilm F12). Without it, that state\n// surfaced only as a raw dolt error from CommitMergeResolution, after the\n// operator had been told \"0 conflicts remain\".\n//\n// Each source is read independently and a MISSING source table is not an\n// error: dolt_schema_conflicts and dolt_constraint_violations are dolt system\n// tables whose presence has varied across versions, and a diagnosis helper\n// must never be the thing that fails the command.\nfunc GetMergeBlockers(ctx context.Context, db DBConn) (storage.MergeBlockers, error) {\n\tvar out storage.MergeBlockers\n\tvar errs []error","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/conflicts.go#L417-L453","documentation":"After issuing the DELETE on dolt_conflicts_<table>, this fires when RowsAffected reports 0 — the conflict row asked for no longer exists. Rather than reporting success for a conflict it did not actually clear, the code aborts so the caller knows the resolution was a no-op.","triggerScenarios":"Resolving a conflict row that was already deleted: another session resolved the same conflict concurrently, a whole-table strategy was applied elsewhere, or the key passed to ResolveConflictRows is stale (the conflict set changed since the key was read).","commonSituations":"Two operators or two automation runs resolving the same merge simultaneously; resolving keys obtained from an earlier listing after a rebase/merge changed state; replaying a resolution script twice.","solutions":["Re-query dolt_conflicts_<table> for the current conflict set; the row is already resolved, so treat this as success and continue.","Run resolution to completion in one pass without interleaving other resolution invocations on the same branch.","If the conflict reappeared (merge restarted), re-run the merge/pull to refresh the conflict table and resolve the new rows.","Deduplicate concurrent resolvers (single session/lock) so only one process deletes conflict rows."],"exampleFix":"// before: resolving keys captured long ago\nerr := ops.ResolveConflictRows(ctx, db, \"issues\", \"theirs\", staleKeys)\n// after: refresh the conflict set first\nrows := listCurrentConflicts(ctx, db, \"issues\") // SELECT our_id FROM dolt_conflicts_issues\nerr = ops.ResolveConflictRows(ctx, db, \"issues\", \"theirs\", keysOf(rows))","handlingStrategy":"try-catch","validationCode":"// Confirm the conflict row still exists before resolving:\nvar n int\n_ = db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_conflicts_issues WHERE our_id = ?\", key).Scan(&n)\nif n == 0 { return nil } // nothing to resolve","typeGuard":null,"tryCatchPattern":"if err := ops.ResolveConflictRows(ctx, db, table, \"theirs\", keys); err != nil {\n  if strings.Contains(err.Error(), \"was not cleared\") {\n    return nil // already resolved by someone else; treat as success\n  }\n  return err\n}","preventionTips":["Treat conflict resolution as idempotent and deduplicate concurrent resolvers.","Refresh the conflict set right before each resolution batch.","Don't replay resolution scripts without re-checking current conflict state."],"tags":["dolt","merge-conflicts","concurrency","idempotency"],"backgroundTag":"conflict-already-resolved","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}