{"record":{"id":"26c9f31e3bffb4bb","repo":"gastownhall/beads","slug":"clear-conflict-for-s-s-w","errorCode":null,"errorMessage":"clear conflict for %s %s: %w","messagePattern":"clear conflict for (.+?) (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/conflicts.go","lineNumber":432,"sourceCode":"\t\t// side under a --theirs invocation, undetectably. But zero is not\n\t\t// proof of that on its own (see conflictTargetStillPresent), so ask\n\t\t// before refusing: an operator who named this row deserves the abort\n\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.","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/conflicts.go#L414-L450","documentation":"This wraps the failure of the DELETE against dolt_conflicts_<table> that marks a conflict row as resolved. If this DELETE fails, dolt still considers the row in conflict even if the data UPDATE (theirs strategy) already succeeded. The %w wrap preserves the underlying SQL error for diagnosis.","triggerScenarios":"Any error from ExecContext on DELETE FROM dolt_conflicts_<table> WHERE our_<keycol> = ? during ResolveConflictRows: connection drop, context cancellation, dolt storage-engine error, permission failure on the conflict table, or a database state that rejects writes (e.g. mid-merge lock).","commonSituations":"Network interruption between client and dolt sql-server; context timeout expiring mid-resolution; concurrent schema changes; permissions issues on dolt system conflict tables in server mode.","solutions":["Inspect the wrapped cause and fix the underlying SQL/connection error first (connectivity, permissions, deadline).","Retry ResolveConflictRows for the affected row once the connection is healthy; per-row resolution is idempotent.","Increase the context timeout or run resolution on a single healthy connection/session.","Check dolt sql-server (or embedded engine) logs if the wrapped cause is opaque."],"exampleFix":"// before: one long, cancellation-prone call\nctx := context.Background()\nerr := ops.ResolveConflictRows(ctx, db, \"issues\", \"theirs\", keys)\n// after: bounded, retryable context\nctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\nvar lastErr error\nfor i := 0; i < 3; i++ {\n  lastErr = ops.ResolveConflictRows(ctx, db, \"issues\", \"theirs\", keys)\n  if lastErr == nil { break }\n  time.Sleep(time.Duration(i+1) * time.Second)\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the DB is reachable and writable before resolving:\nif err := db.PingContext(ctx); err != nil { return err }","typeGuard":null,"tryCatchPattern":"if err := ops.ResolveConflictRows(ctx, db, table, \"theirs\", keys); err != nil {\n  log.Printf(\"clear conflict failed: %v\", err) // %w chain shows SQL cause\n  if isTransient(err) { return retryWithBackoff(ctx, db, table, keys) }\n  return err\n}","preventionTips":["Use a context with an adequate timeout for the whole resolution pass.","Ping or health-check the connection before long resolution batches.","Avoid cancelling the context mid-resolution; cancellation surfaces as this wrapped DELETE error."],"tags":["dolt","sql-error","merge-conflicts","delete-failure"],"backgroundTag":"conflict-resolution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}