{"record":{"id":"101e051ae406a512","repo":"gastownhall/beads","slug":"rows-affected-w","errorCode":null,"errorMessage":"rows affected: %w","messagePattern":"rows affected: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/issueops/bulk_ops.go","lineNumber":220,"sourceCode":"\tif _, err := tx.ExecContext(ctx,\n\t\t`DELETE FROM leases WHERE issue_id IN (SELECT id FROM issues WHERE source_repo = ?)`, sourceRepo); err != nil {\n\t\treturn 0, fmt.Errorf(\"delete leases: %w\", err)\n\t}\n\n\t// Edges are journaled before the rows go, while their source snapshots can\n\t// still be read.\n\tif err := RecordDependencyRemovalsForIssuesInTx(ctx, tx, issueIDs); err != nil {\n\t\treturn 0, fmt.Errorf(\"journal dependency removals for source-repo delete: %w\", err)\n\t}\n\n\tresult, err := tx.ExecContext(ctx, `DELETE FROM issues WHERE source_repo = ?`, sourceRepo)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"delete issues: %w\", err)\n\t}\n\n\trowsAffected, err := result.RowsAffected()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"rows affected: %w\", err)\n\t}\n\n\t// Journal each deleted issue in the same transaction. issueIDs is the exact\n\t// set removed by the DELETE above (both were scoped to source_repo), so\n\t// there are no phantom records here. The source-repo bulk delete plumbing\n\t// carries no actor, so the rows record none.\n\tfor _, id := range issueIDs {\n\t\tif err := RecordDeleteInTx(ctx, tx, id, \"\"); err != nil {\n\t\t\treturn int(rowsAffected), err\n\t\t}\n\t}\n\n\tif err := RecomputeIsBlockedInTx(ctx, tx, affectedIssues, affectedWisps); err != nil {\n\t\treturn int(rowsAffected), fmt.Errorf(\"recompute is_blocked after source-repo delete: %w\", err)\n\t}\n\n\treturn int(rowsAffected), nil\n}","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/bulk_ops.go#L202-L238","documentation":"After the DELETE, result.RowsAffected() is read to report how many issues were removed; an error there is wrapped as \"rows affected: %w\". The delete itself succeeded, but the affected-row count could not be retrieved.","triggerScenarios":"RowsAffected returns an error, which is rare and driver-specific: some drivers cannot report affected rows for certain statements or connection states.","commonSituations":"Using a driver or middleware wrapper that does not implement RowsAffected; exotic storage backends behind the same sql.Tx interface.","solutions":["Check the wrapped error and which driver is configured; switch to a driver that supports RowsAffected","Treat the delete as successful and tolerate a missing count if the count is only informational","Pin to the standard, supported database driver for bd"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// verify driver supports RowsAffected with a trivial statement\nres, err := db.Exec(\"SELECT 1\")\n_, rerr := res.RowsAffected() // fail fast at startup if unsupported","typeGuard":"var unsupported interface{ Error() string }\n_ = errors.As(err, &unsupported) // driver-specific RowsAffected limitation","tryCatchPattern":"n, err := DeleteIssuesBySourceRepoInTx(ctx, tx, repo)\nif err != nil && strings.Contains(err.Error(), \"rows affected\") {\n    // deletion succeeded; degrade gracefully by treating the count as unknown\n    log.Warn(\"could not read affected-row count\", \"err\", err)\n    return nil\n}","preventionTips":["Use bd's supported standard driver; avoid middleware that drops RowsAffected","Treat the count as informational, not transactional","Add a startup smoke test for driver capability"],"tags":["database","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"}