{"record":{"id":"0a307c576b477d99","repo":"gastownhall/beads","slug":"per-row-conflict-resolution-is-not-supported-for-t","errorCode":null,"errorMessage":"per-row conflict resolution is not supported for table %s; resolve the whole table instead","messagePattern":"per-row conflict resolution is not supported for table (.+?); resolve the whole table instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/conflicts.go","lineNumber":241,"sourceCode":"// conflictRowKeyColumn support it, and only modify/modify rows (present on\n// both sides): a delete/modify or add/add row is refused by name rather than\n// guessed at, because \"ours\" and \"theirs\" do not describe what the operator\n// wants when one side deleted the row.\n//\n// db must be a SINGLE session (a pinned *sql.Conn, or a *sql.Tx): the\n// conflict-tolerance flags set here have to be visible to the writes that\n// follow, and dolt refuses to commit a transaction touching a table with live\n// conflicts without them.\nfunc ResolveConflictRows(ctx context.Context, db DBConn, table string, keys []string, strategy string) (int, error) {\n\tif err := ValidateConflictTable(table); err != nil {\n\t\treturn 0, err\n\t}\n\tif err := ValidateConflictStrategy(strategy); err != nil {\n\t\treturn 0, err\n\t}\n\tkeyCol, ok := conflictRowKeyColumn[table]\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"per-row conflict resolution is not supported for table %s; resolve the whole table instead\", table)\n\t}\n\tif len(keys) == 0 {\n\t\treturn 0, nil\n\t}\n\t// A conflicted table cannot be written — nor the session committed —\n\t// without dolt's conflict-tolerance flags (the same pair MergeAndSettle\n\t// sets). They are session state, which is why db must be one session.\n\tif _, err := db.ExecContext(ctx, \"SET @@dolt_allow_commit_conflicts = 1\"); err != nil {\n\t\treturn 0, fmt.Errorf(\"set dolt_allow_commit_conflicts: %w\", err)\n\t}\n\tif _, err := db.ExecContext(ctx, \"SET @@dolt_force_transaction_commit = 1\"); err != nil {\n\t\treturn 0, fmt.Errorf(\"set dolt_force_transaction_commit: %w\", err)\n\t}\n\n\tresolved := 0\n\tfor _, key := range keys {\n\t\trow, err := loadConflictRow(ctx, db, table, keyCol, key)\n\t\tif err != nil {","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/conflicts.go#L223-L259","documentation":"ResolveConflictRows refuses to resolve conflicts row-by-row for a table that is not listed in conflictRowKeyColumn, i.e. the library has no known primary-key column for mapping \"our_/their_\" prefixed conflict rows to user rows. Only tables registered with a row-key column support per-row resolution; others must be resolved as a whole table.","triggerScenarios":"Calling ResolveConflictRows(ctx, db, table, keys, strategy) with a table name that lacks an entry in the library's conflictRowKeyColumn map — a misspelled table name, a table the library doesn't recognize, or a genuinely unsupported table.","commonSituations":"Passing a table name in different case or with schema qualifier (\"main.issues\") that misses the map lookup; trying per-row resolution on a table the library supports only at whole-table granularity; calling on a newly added table before the library registers it.","solutions":["Check the exact supported table name (no schema qualifier, exact case)","Fall back to whole-table resolution (e.g. dolt conflicts resolve / MergeWithStrategy on the table) for unsupported tables","If the table should be supported, file/extend the conflictRowKeyColumn registration in the library","Verify with SupportsRowResolve(table) before calling"],"exampleFix":"// before\nn, err := ResolveConflictRows(ctx, db, \"main.issues\", keys, strategy)\n// after\nif versioncontrolops.SupportsRowResolve(\"issues\") {\n    n, err := ResolveConflictRows(ctx, db, \"issues\", keys, strategy)\n} else {\n    err := resolveWholeTable(ctx, db, \"issues\", strategy)\n}","handlingStrategy":"validation","validationCode":"if !versioncontrolops.SupportsRowResolve(table) {\n    return fmt.Errorf(\"use whole-table resolution for %q\", table)\n}","typeGuard":"func canResolveRows(table string) bool {\n    return versioncontrolops.SupportsRowResolve(table)\n}","tryCatchPattern":"n, err := versioncontrolops.ResolveConflictRows(ctx, db, table, keys, strat)\nif err != nil && strings.Contains(err.Error(), \"per-row conflict resolution is not supported\") {\n    return resolveWholeTable(ctx, db, table, strat) // fallback path\n}","preventionTips":["Gate per-row resolution on SupportsRowResolve(table)","Use exact table names without schema qualifiers or case changes","Keep a lookup of supported tables in sync with library releases"],"tags":["validation","conflict-resolution","dolt","unsupported-table"],"backgroundTag":"unsupported-operation","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}