{"record":{"id":"a21ea774d52f2335","repo":"gastownhall/beads","slug":"delete-issues-w-a21ea7","errorCode":null,"errorMessage":"delete issues: %w","messagePattern":"delete issues: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/delete.go","lineNumber":321,"sourceCode":"\t\tif err := deleteIssueRowInTx(ctx, tx, id, true); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"delete wisp %s: %w\", id, err)\n\t\t}\n\t}\n\n\ttotalRegularsDeleted := 0\n\tfor i := 0; i < len(set.RegularIDs); i += deleteBatchSize {\n\t\tend := i + deleteBatchSize\n\t\tif end > len(set.RegularIDs) {\n\t\t\tend = len(set.RegularIDs)\n\t\t}\n\t\tbatch := set.RegularIDs[i:end]\n\t\tbatchInClause, batchArgs := buildSQLInClause(batch)\n\n\t\tdeleteResult, err := tx.ExecContext(ctx,\n\t\t\tfmt.Sprintf(`DELETE FROM issues WHERE id IN (%s)`, batchInClause),\n\t\t\tbatchArgs...)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"delete issues: %w\", err)\n\t\t}\n\t\trowsAffected, _ := deleteResult.RowsAffected()\n\t\ttotalRegularsDeleted += int(rowsAffected)\n\n\t\t// Deleted issues hold no leases.\n\t\tif _, err := tx.ExecContext(ctx,\n\t\t\tfmt.Sprintf(`DELETE FROM leases WHERE issue_id IN (%s)`, batchInClause),\n\t\t\tbatchArgs...); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"delete leases: %w\", err)\n\t\t}\n\t}\n\tresult.DeletedCount = totalRegularsDeleted + len(set.WispIDs)\n\n\t// Journal every regular issue this bulk/cascade delete removed. Wisps went\n\t// through deleteIssueRowInTx above, which journals each itself; set.All is\n\t// cascade-expanded, so this records cascade deletes too. The delete\n\t// plumbing carries no actor, so the rows record none.\n\tfor _, id := range journaledDeletes {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/delete.go#L303-L339","documentation":"DeleteResolvedSetInTx fails with this when the batched `DELETE FROM issues WHERE id IN (...)` statement errors. Regular (non-wisp) issues are removed in batches of deleteBatchSize inside one transaction; any SQL-level failure aborts the whole delete.","triggerScenarios":"DeleteIssuesInTx/DeleteInTx executing a cascade or bulk delete where the DELETE statement fails — too many parameters for the driver, table lock/timeout, or connection loss during tx.ExecContext.","commonSituations":"Very large batch deletes exceeding driver parameter limits on some engines; database locked by another writer (SQLite busy); network interruption to a remote Dolt server.","solutions":["Check the wrapped driver error (lock timeout, too many parameters, connection reset)","Reduce delete set size or retry when the DB is not contended","For SQLite busy errors, raise the busy timeout / close other writers","Ensure the schema is migrated before deleting"],"exampleFix":"// before\nresult, err := tx.ExecContext(ctx, fmt.Sprintf(`DELETE FROM issues WHERE id IN (%s)`, batchInClause), batchArgs...)\nif err != nil { return nil, fmt.Errorf(\"delete issues: %w\", err) }\n// after — same error path; avoid busy-lock by configuring the driver\n// e.g. dsn := \"file:beads.db?_busy_timeout=5000\"","handlingStrategy":"try-catch","validationCode":"// confirm target IDs exist and the DB is writable before the bulk delete\nif err := db.PingContext(ctx); err != nil { return err }\n// optionally: verify no other process holds a write lock (SQLite)","typeGuard":null,"tryCatchPattern":"if _, err := DeleteIssuesInTx(ctx, tx, ids, opts); err != nil {\n\tif strings.Contains(err.Error(), \"delete issues: \") {\n\t\tlog.Printf(\"batch DELETE failed: %v\", err) // inspect wrapped driver error\n\t}\n\treturn err\n}","preventionTips":["Split very large delete sets into smaller calls to avoid driver parameter limits","Raise SQLite busy timeout or serialize writers","Apply schema migrations before running new binaries against old DBs"],"tags":["database","delete","sql","transaction"],"backgroundTag":"sql-delete-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}