{"record":{"id":"c28f8a44d1b7ab51","repo":"gastownhall/beads","slug":"query-conflict-for-s-s-w","errorCode":null,"errorMessage":"query conflict for %s %s: %w","messagePattern":"query conflict for (.+?) (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/conflicts.go","lineNumber":309,"sourceCode":"\tfor i, c := range r.cols {\n\t\tside, field, ok := splitConflictColumn(c)\n\t\tif !ok || side != \"their\" || conflictMetaSuffixes[field] || field == keyCol {\n\t\t\tcontinue\n\t\t}\n\t\tnames = append(names, field)\n\t\tvals = append(vals, r.vals[i])\n\t}\n\treturn names, vals\n}\n\n// loadConflictRow fetches the single conflict row for key. It matches on\n// either side's key column so a row only one side has is *found* and then\n// refused with a precise message, rather than reported as \"no conflict\".\nfunc loadConflictRow(ctx context.Context, db DBConn, table, keyCol, key string) (rawConflictRow, error) {\n\tq := fmt.Sprintf(\"SELECT * FROM `dolt_conflicts_%s` WHERE `our_%s` = ? OR `their_%s` = ?\", table, keyCol, keyCol) //nolint:gosec // identifiers validated\n\trows, err := db.QueryContext(ctx, q, key, key)\n\tif err != nil {\n\t\treturn rawConflictRow{}, fmt.Errorf(\"query conflict for %s %s: %w\", table, key, err)\n\t}\n\tdefer func() { _ = rows.Close() }()\n\n\tcols, err := rows.Columns()\n\tif err != nil {\n\t\treturn rawConflictRow{}, fmt.Errorf(\"conflict columns for table %s: %w\", table, err)\n\t}\n\tif !rows.Next() {\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn rawConflictRow{}, fmt.Errorf(\"query conflict for %s %s: %w\", table, key, err)\n\t\t}\n\t\treturn rawConflictRow{}, fmt.Errorf(\"no live conflict for %s %s\", table, key)\n\t}\n\tvals := make([]any, len(cols))\n\tptrs := make([]any, len(cols))\n\tfor i := range vals {\n\t\tptrs[i] = &vals[i]\n\t}","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/conflicts.go#L291-L327","documentation":"loadConflictRow failed while querying dolt_conflicts_<table> for a single row by key, matching either our_<keyCol> or their_<keyCol>. This wraps the underlying query error, meaning the SELECT itself failed to execute — connection, permission, or server-side failure — not merely absence of the row.","triggerScenarios":"Called from ResolveConflictRows per key; the SELECT fails because the connection dropped, the context was cancelled, the session lost the conflict-tolerance flags, or the server rejected the query.","commonSituations":"Long per-key resolution loops exceeding context deadline; server restart mid-loop; the conflicted table was resolved concurrently by another session, invalidating conflict metadata.","solutions":["Check the wrapped error for root cause (timeout vs connection vs SQL error)","Retry the key's resolution; per-row resolution is idempotent once already resolved","Extend the context deadline when resolving many keys","Ensure no other session is resolving the same conflicts concurrently"],"exampleFix":"// before\nctx := context.Background()\nfor _, key := range keys { ResolveConflictRows(ctx, db, table, []string{key}, strat) }\n// after\nctx, cancel := context.WithTimeout(context.Background(), time.Duration(len(keys))*500*time.Millisecond)\ndefer cancel()","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"n, err := versioncontrolops.ResolveConflictRows(ctx, db, table, keys, strat)\nif err != nil && strings.Contains(err.Error(), \"query conflict for \"+table) {\n    if isTransient(err) {\n        n, err = versioncontrolops.ResolveConflictRows(ctx, db, table, keys, strat) // idempotent retry\n    }\n}","preventionTips":["Size the context deadline to the number of keys being resolved","Prevent concurrent resolvers on the same conflicted table","Keep the session's conflict-tolerance flags set for the whole loop"],"tags":["database","dolt","sql","conflict-resolution"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}