{"record":{"id":"8fce80d916570c43","repo":"gastownhall/beads","slug":"failed-to-iterate-dolt-status-w","errorCode":null,"errorMessage":"failed to iterate dolt_status: %w","messagePattern":"failed to iterate dolt_status: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":3085,"sourceCode":"\tvar tables []string\n\tconfigDirty := false\n\tfor rows.Next() {\n\t\tvar table string\n\t\tif err := rows.Scan(&table); err != nil {\n\t\t\t_ = rows.Close()\n\t\t\treturn fmt.Errorf(\"failed to scan dolt_status: %w\", err)\n\t\t}\n\t\tif table == \"config\" {\n\t\t\tconfigDirty = true\n\t\t\tif mode == configExclude {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\ttables = append(tables, table)\n\t}\n\t_ = rows.Close()\n\tif err := rows.Err(); err != nil {\n\t\treturn fmt.Errorf(\"failed to iterate dolt_status: %w\", err)\n\t}\n\n\t// GH#2455 + GH#2474: the pre-pull auto-commit includes config so user kv.*\n\t// writes sync, but it must NOT auto-commit any internal (non-kv.) config key.\n\t// Refuse before staging anything so the merge is never concluded over an\n\t// unsafe config row; the operator commits those explicitly.\n\tif configDirty && mode == configIncludeUserKVOnly {\n\t\tif err := s.assertDirtyConfigUserKVOnly(ctx, conn); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif len(tables) == 0 {\n\t\t// A merge resolution with a clean working set is NOT a no-op: it is\n\t\t// the `--ours` case, where our values already stood and resolving the\n\t\t// conflict dirtied nothing. Returning here left is_merging true while\n\t\t// the caller reported \"Merge committed\", and the next pull re-wedged\n\t\t// on the unconcluded merge (wy-36ilm, caught by the F9 integration","sourceCodeStart":3067,"sourceCodeEnd":3103,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L3067-L3103","documentation":"After all rows are consumed, the code checks rows.Err() to catch errors that terminated iteration early (connection drop, server abort mid-result-set). This error wraps that condition. The table list may be incomplete, so the commit is deliberately aborted rather than staging a partial set of dirty tables.","triggerScenarios":"The dolt result stream breaks during iteration: network drop to a remote Dolt server, process killed, context deadline exceeded while reading rows, or driver-level protocol error.","commonSituations":"Long table lists read over flaky network to a remote Dolt server; context timeout too short for large working sets; embedded Dolt restarted concurrently by another bd process.","solutions":["Inspect the wrapped error; if it is a context deadline, retry with a larger timeout.","For remote Dolt, check network stability and server logs for connection aborts.","Re-run the commit/sync; since staging had not started, there is no partial commit to clean up.","Reduce concurrency against the same database so the pinned session is not disrupted mid-iteration."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure adequate context budget for large working sets\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)\ndefer cancel()","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to iterate dolt_status\") {\n\t// safe to retry: nothing staged yet\n\treturn retryCommit(ctx, msg)\n}","preventionTips":["Use long-enough timeouts for repos with many dirty tables.","Keep connections to remote Dolt stable (keepalives, no aggressive proxy idle reaping).","Don't restart the engine mid-sync.","Check rows.Err() handling in any custom code paths."],"tags":["go","dolt","sql","rows-iteration"],"backgroundTag":"dolt-status-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}