{"record":{"id":"5589b8a52f662a34","repo":"gastownhall/beads","slug":"scan-dirty-config-key-w","errorCode":null,"errorMessage":"scan dirty config key: %w","messagePattern":"scan dirty config key: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":3193,"sourceCode":"// namespace (not just kv.memory.*) un-wedges generic `bd kv set` writes too: a\n// kv.* row is this clone's own data, exactly as safe to auto-commit as a memory,\n// and a genuine kv.* merge conflict is still left for the operator because\n// auto-resolution stays kv.memory.*-only (configConflictsAreMemoryConvergent).\n// config's primary key is `key`, so dolt_diff exposes to_key/from_key; an add or\n// delete leaves one side NULL, so COALESCE picks whichever key the change carries.\nfunc (s *DoltStore) assertDirtyConfigUserKVOnly(ctx context.Context, conn *sql.Conn) error {\n\trows, err := conn.QueryContext(ctx,\n\t\t\"SELECT COALESCE(to_key, from_key) FROM dolt_diff('HEAD', 'WORKING', 'config')\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"inspect dirty config before pull: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar unsafe []string\n\tfor rows.Next() {\n\t\tvar key sql.NullString\n\t\tif err := rows.Scan(&key); err != nil {\n\t\t\treturn fmt.Errorf(\"scan dirty config key: %w\", err)\n\t\t}\n\t\tif key.Valid && !strings.HasPrefix(key.String, kvkeys.Prefix) {\n\t\t\tunsafe = append(unsafe, key.String)\n\t\t}\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn fmt.Errorf(\"iterate dirty config diff: %w\", err)\n\t}\n\tif len(unsafe) > 0 {\n\t\treturn fmt.Errorf(\"refusing to auto-commit %d dirty internal config key(s) before pull: %s; \"+\n\t\t\t\"only user %s* keys auto-commit before a pull (GH#2455) — commit or revert \"+\n\t\t\t\"these explicitly with `bd dolt commit` first\", len(unsafe), strings.Join(unsafe, \", \"), kvkeys.Prefix)\n\t}\n\treturn nil\n}\n\n// CommitWithConfig creates a Dolt commit that includes the config table.\n// Use this instead of Commit when the caller intentionally modified config","sourceCodeStart":3175,"sourceCodeEnd":3211,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L3175-L3211","documentation":"While iterating the dolt_diff rows for the config table, each key is scanned into a sql.NullString (COALESCE(to_key, from_key) can be NULL in theory). This error wraps a rows.Scan failure on that scan, aborting the safety check and therefore the merge/pull before staging. The scan into NullString rarely fails, so this usually indicates a driver/protocol problem rather than data shape.","triggerScenarios":"The scan fails despite sql.NullString: driver protocol error mid-row, corrupted result stream, or a Dolt version returning the diff columns with an unexpected wire type.","commonSituations":"Remote Dolt connection degraded mid-result; version skew between the Go driver and Dolt server; interrupted embedded engine during the pull path.","solutions":["Inspect the wrapped driver message; retry the pull with a fresh connection.","Align go-mysql-driver and Dolt server versions if the wire type differs from expectations.","Verify the diff query manually in a Dolt SQL shell to rule out server-side anomalies.","Re-run bd sync/pull after fixing; the abort is pre-staging so no partial merge state remains."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// sanity-run the same diff manually before pull:\n// SELECT COALESCE(to_key, from_key) FROM dolt_diff('HEAD','WORKING','config');","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"scan dirty config key\") {\n\t// driver/protocol issue — retry on fresh connection, then check versions\n}","preventionTips":["Match go-mysql-driver and Dolt server versions.","Avoid network interruptions to remote Dolt during sync.","Re-run pull after the failure — abort is pre-staging, so no partial state.","Inspect the diff output manually if the failure repeats."],"tags":["go","dolt","sql","scan","config"],"backgroundTag":"dolt-diff-config-inspection-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}