{"record":{"id":"ea9531df26270f1a","repo":"gastownhall/beads","slug":"failed-to-iterate-issues-for-prefix-q-w","errorCode":null,"errorMessage":"failed to iterate issues for prefix %q: %w","messagePattern":"failed to iterate issues for prefix %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/helpers.go","lineNumber":304,"sourceCode":"\tdefer rows.Close()\n\n\tmaxNum := 0\n\tpfxDash := prefix + \"-\"\n\tfor rows.Next() {\n\t\tvar id string\n\t\tif err := rows.Scan(&id); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tsuffix := strings.TrimPrefix(id, pfxDash)\n\t\tif strings.Contains(suffix, \".\") {\n\t\t\tcontinue // skip child IDs\n\t\t}\n\t\tif n, err := strconv.Atoi(suffix); err == nil && n > maxNum {\n\t\t\tmaxNum = n\n\t\t}\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn fmt.Errorf(\"failed to iterate issues for prefix %q: %w\", prefix, err)\n\t}\n\n\tif maxNum > 0 {\n\t\t_, err = tx.ExecContext(ctx, \"INSERT INTO issue_counter (prefix, last_id) VALUES (?, ?)\", prefix, maxNum)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to seed issue counter for prefix %q at %d: %w\", prefix, maxNum, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// GetAdaptiveIDLengthTx returns the appropriate hash length based on database size.\n//\n//nolint:gosec // G201: table is a hardcoded constant\nfunc GetAdaptiveIDLengthTx(ctx context.Context, tx DBTX, table, prefix string) (int, error) {\n\tvar count int\n\terr := tx.QueryRowContext(ctx, fmt.Sprintf(`\n\t\tSELECT COUNT(*)","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/helpers.go#L286-L322","documentation":"After iterating rows in SeedCounterFromExistingIssuesTx, rows.Err() returned non-nil, meaning the row iteration was aborted by a driver/network error mid-scan (not a normal end of results).","triggerScenarios":"Long issues table scan during counter seeding interrupted by connection drop, Dolt server restart, or context cancellation while rows.Next() was streaming.","commonSituations":"Large issue databases over a flaky connection to a remote Dolt server; context timeout (ctx deadline exceeded) during seeding; server killed mid-query.","solutions":["Retry the ID-generation operation; seeding is idempotent and will re-scan.","Increase the context timeout / remove the deadline so large scans can complete.","Check connectivity to the Dolt server (dolt sql-server logs) for restarts or dropped connections.","If persistent, run the seeding locally against the .beads DB rather than over the network."],"exampleFix":"// before\nctx := context.Background() // no deadline, but network drops abort scan\n// after: give the seeding scan explicit headroom and retry\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)\ndefer cancel()\nerr := retry.OnError(3, isTransient, func() error { return generateID(ctx) })","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := retry.Do(func() error {\n    return storage.GenerateIssueIDInTable(ctx, tx, \"issues\", prefix, issue)\n}, retry.Attempts(3), retry.RetryIf(isNetworkError))","preventionTips":["Give long seeding scans a generous context timeout.","Keep network links to dolt sql-server stable; monitor for server restarts.","Run counter seeding against the local .beads DB rather than over WAN where possible."],"tags":["database","network","iteration","go"],"backgroundTag":"rows-iteration-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}