{"record":{"id":"e427454e5a3bb2a9","repo":"gastownhall/beads","slug":"failed-to-check-rows-affected-after-seeding-for-pr-e42745","errorCode":null,"errorMessage":"failed to check rows affected after seeding for prefix %q: %w","messagePattern":"failed to check rows affected after seeding for prefix %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/helpers.go","lineNumber":251,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"failed to increment issue counter for prefix %q: %w\", prefix, err)\n\t}\n\n\trowsAffected, err := res.RowsAffected()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to check rows affected for issue counter prefix %q: %w\", prefix, err)\n\t}\n\n\tif rowsAffected == 0 {\n\t\tif seedErr := SeedCounterFromExistingIssuesTx(ctx, tx, prefix); seedErr != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to seed issue counter for prefix %q: %w\", prefix, seedErr)\n\t\t}\n\t\tres, err = tx.ExecContext(ctx, \"UPDATE issue_counter SET last_id = last_id + 1 WHERE prefix = ?\", prefix)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to increment issue counter after seeding for prefix %q: %w\", prefix, err)\n\t\t}\n\t\trowsAffected, err = res.RowsAffected()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to check rows affected after seeding for prefix %q: %w\", prefix, err)\n\t\t}\n\t\tif rowsAffected == 0 {\n\t\t\t_, err = tx.ExecContext(ctx, \"INSERT INTO issue_counter (prefix, last_id) VALUES (?, 1)\", prefix)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to insert initial issue counter for prefix %q: %w\", prefix, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar nextID int\n\terr = tx.QueryRowContext(ctx, \"SELECT last_id FROM issue_counter WHERE prefix = ?\", prefix).Scan(&nextID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read issue counter after increment for prefix %q: %w\", prefix, err)\n\t}\n\treturn fmt.Sprintf(\"%s-%d\", prefix, nextID), nil\n}\n\n// SeedCounterFromExistingIssuesTx scans existing issues to find the highest numeric suffix","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/helpers.go#L233-L269","documentation":"After the post-seed increment, NextCounterIDTx calls res.RowsAffected() a second time to confirm the counter row was actually updated. This error wraps a failure of that RowsAffected call — the driver could not report the affected row count for the post-seed UPDATE. It indicates a driver or connection problem rather than missing data.","triggerScenarios":"Calling NextCounterIDTx on a prefix that required seeding, where the driver fails to report rows affected for the second UPDATE: broken connection between ExecContext and RowsAffected, a DBTX stub (mock) that errors on result introspection, or a driver lacking RowsAffected support for this statement.","commonSituations":"Test suites using misconfigured sqlmock or stub DBTX for the second statement; flaky network to a remote Dolt server dropping results mid-response; driver incompatibilities after a dependency upgrade.","solutions":["Inspect the wrapped driver error; reconnect and retry if it signals connection loss.","Fix the mock or stub to return a proper Result (sqlmock.NewResult(0, 1)) for the post-seed UPDATE expectation.","Pin or upgrade to a driver version whose RowsAffected works for UPDATE results.","Retry issue creation if the cause is a transient network drop."],"exampleFix":"// before: mock.ExpectExec(\"UPDATE issue_counter\").WillReturnResult(invalidResult) // after: mock.ExpectExec(\"UPDATE issue_counter\").WillReturnResult(sqlmock.NewResult(0, 1))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isPostSeedRowsAffectedErr(err error) bool { return err != nil && strings.Contains(err.Error(), \"failed to check rows affected after seeding for prefix\") }","tryCatchPattern":"id, err := GenerateIssueIDInTable(ctx, tx, prefix, issue); if isPostSeedRowsAffectedErr(err) { return fmt.Errorf(\"rows-affected unavailable: %w\", err) } // fix driver or mock, then retry once","preventionTips":["Configure test mocks (sqlmock) to return valid Results for every statement, including post-seed UPDATEs.","Keep network connections to the Dolt server stable; prefer local unix socket for embedded use.","Pin tested driver versions and re-run integration tests after upgrades.","Add a one-shot retry for transient result-read failures."],"tags":["database","sql","driver","rows-affected"],"backgroundTag":"driver-rows-affected-unsupported","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}