{"record":{"id":"b0784b463f8ae0d9","repo":"gastownhall/beads","slug":"query-config-conflicts-w","errorCode":null,"errorMessage":"query config conflicts: %w","messagePattern":"query config conflicts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/mergesettle.go","lineNumber":666,"sourceCode":"}\n\n// configConflictsAreMemoryConvergent reports whether every conflicted config\n// row is a persistent-memory row (key prefixed memoryConfigKeyPrefix). Memories\n// are the only config class safe to auto-resolve with --theirs: like metadata,\n// all clones pulling from the same remote converge on the remote's value (a\n// local edit to the same memory key loses, the same convergent trade-off\n// metadata makes). Any other config key in conflict — issue_prefix above all,\n// whose stale-value sweep GH#2455 specifically guards against — is a real\n// semantic conflict, so the whole config table is left for the operator.\n//\n// The key column is config's primary key, so a same-key conflict carries the\n// identical key on both sides; an add/delete conflict leaves one side NULL. A\n// row is convergent only if every key it presents is a memory key.\nfunc configConflictsAreMemoryConvergent(ctx context.Context, db DBConn) (bool, error) {\n\trows, err := db.QueryContext(ctx, `\n\t\tSELECT our_key, their_key FROM dolt_conflicts_config`)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"query config conflicts: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tfor rows.Next() {\n\t\tvar ourKey, theirKey sql.NullString\n\t\tif err := rows.Scan(&ourKey, &theirKey); err != nil {\n\t\t\treturn false, fmt.Errorf(\"scan config conflict: %w\", err)\n\t\t}\n\t\tfor _, k := range []sql.NullString{ourKey, theirKey} {\n\t\t\tif k.Valid && !strings.HasPrefix(k.String, memoryConfigKeyPrefix) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn true, rows.Err()\n}\n\n// resolvedConfigConflictKeys returns the keys of the config rows currently in","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/mergesettle.go#L648-L684","documentation":"This error is returned by configConflictsAreMemoryConvergent when the SQL query against the dolt_conflicts_config system table fails. During a Dolt merge with unresolved conflicts, the library reads the conflict rows to decide whether all conflicted config keys are memory keys (safe to auto-resolve with --theirs); if the query itself errors, the error is wrapped with the 'query config conflicts:' prefix and bubbles up to TryAutoResolveMergeConflicts, aborting auto-resolution. It is a wrapper around the underlying database driver error, not a logic failure in the checker itself.","triggerScenarios":"Calling TryAutoResolveMergeConflicts (typically via bd's merge/pull version-control path) while the underlying Dolt database is in a conflicted state and the query 'SELECT our_key, their_key FROM dolt_conflicts_config' fails — e.g. the dolt_conflicts_config table does not exist (no config conflicts on the Dolt version in use, or schema drift between Dolt versions), the DB connection is broken/closed, the transaction was aborted, or the storage driver returns an I/O or lock error.","commonSituations":"Older or newer Dolt server versions that don't expose per-table dolt_conflicts_* tables the same way; running against a database that was never actually merged (table absent); an embedded Dolt connection that has been closed or hit a flock error; disk/IO failures mid-merge; mixing bd binary versions where the merge was performed by a different Dolt engine version.","solutions":["Run the merge/resolve step again — transient driver or connection errors usually clear on retry once the Dolt database is reachable.","Check that a merge actually left config conflicts: run 'CALL DOLT_CONFLICTS_RESOLVE' listing or query SHOW TABLES to confirm dolt_conflicts_config exists in this Dolt version.","Verify the Dolt server/embedded engine version matches what this bd build expects; upgrade or downgrade so the dolt_conflicts_config system table is available.","If the connection is dead, reopen the database (re-run bd open / restart the Dolt SQL server) before retrying the auto-resolve.","If auto-resolution keeps failing, resolve conflicts manually (dolt conflicts resolve / bd resolve) so the pre-check is never needed."],"exampleFix":"// before: query assumes the conflict table always exists\nrows, err := db.QueryContext(ctx, `SELECT our_key, their_key FROM dolt_conflicts_config`)\nif err != nil {\n    return false, fmt.Errorf(\"query config conflicts: %w\", err)\n}\n// after: tolerate a missing conflict table (no config conflicts) explicitly\nrows, err := db.QueryContext(ctx, `SELECT our_key, their_key FROM dolt_conflicts_config`)\nif err != nil {\n    if isNoSuchTableErr(err) { // e.g. information_schema check or driver error code\n        return true, nil // no config conflict rows -> trivially convergent\n    }\n    return false, fmt.Errorf(\"query config conflicts: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Before invoking the auto-resolve, verify the repo is in a conflicted state\n// and the conflict table is reachable:\nvar n int\nerr := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dolt_conflicts_config\").Scan(&n)\nif err != nil {\n    // table missing or DB unreachable — resolve manually or reconnect first\n    return fmt.Errorf(\"config conflict preflight failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := TryAutoResolveMergeConflicts(ctx, db)\nvar qErr *QueryConflictError // or errors.As on the wrapped driver error\nif err != nil {\n    if errors.Is(err, sql.ErrConnDone) || errors.Is(err, driver.ErrBadConn) {\n        // reconnect and retry once\n    } else {\n        // fall back to manual conflict resolution\n        log.Warn(\"auto-resolve skipped; resolve conflicts manually\", \"err\", err)\n    }\n}","preventionTips":["Keep the Dolt engine and bd binary versions aligned so dolt_conflicts_* tables always exist as expected.","Check database connectivity before starting merges or auto-resolution.","Only enter auto-resolve after confirming a merge actually left unresolved conflicts.","Retry transient driver errors once before falling back to manual resolution.","Run 'bd doctor' periodically to catch embedded storage issues early."],"tags":["dolt","merge-conflicts","sql-query","storage"],"backgroundTag":"dolt-conflicts-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}