{"record":{"id":"424214e50731f86c","repo":"gastownhall/beads","slug":"delete-wisp-aux-rows-w","errorCode":null,"errorMessage":"delete wisp aux rows: %w","messagePattern":"delete wisp aux rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/wisps.go","lineNumber":477,"sourceCode":"\t\targs...)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to batch delete wisps: %w\", err)\n\t}\n\trowsAffected, _ := result.RowsAffected()\n\n\t// The batched wisp delete surface carries no actor, so the rows record none.\n\tfor _, id := range deletedIDs {\n\t\tif err := issueops.RecordDeleteInTx(ctx, tx, id, \"\"); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\tif err := issueops.DeleteWispsFromDependenciesInTx(ctx, tx, ids); err != nil {\n\t\treturn 0, err\n\t}\n\n\tif err := deleteWispAuxRowsInTx(ctx, tx, ids); err != nil {\n\t\treturn 0, fmt.Errorf(\"delete wisp aux rows: %w\", err)\n\t}\n\n\tif err := issueops.RecomputeIsBlockedInTx(ctx, tx, affectedIssues, affectedWisps); err != nil {\n\t\treturn 0, fmt.Errorf(\"recompute is_blocked after batched wisp delete: %w\", err)\n\t}\n\n\tif err := s.commitSQLTx(ctx, \"commit batch wisp delete\", tx); err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn int(rowsAffected), nil\n}\n\n// claimWisp atomically claims a wisp.\n// Delegates SQL work to issueops.ClaimIssueInTx; no Dolt versioning needed\n// since wisps live in dolt_ignored tables.\nfunc (s *DoltStore) claimWisp(ctx context.Context, id string, actor string) error {\n\ttx, err := s.db.BeginTx(ctx, nil)","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/wisps.go#L459-L495","documentation":"This error wraps failures from deleteWispAuxRowsInTx, which removes auxiliary rows associated with the wisps being deleted (side tables keyed by wisp id) after the main wisps DELETE succeeded. If aux cleanup fails, the transaction rolls back entirely so wisps are never deleted while their aux rows linger.","triggerScenarios":"DeleteWisps path when the aux-row DELETE statements (e.g. labels, comments, or other wisp-keyed tables) fail: lost connection, write timeout, missing aux table, or foreign-key/constraint errors in the aux schema.","commonSituations":"Partially-migrated database where an aux table is missing or renamed; aux tables grown large so the delete exceeds Dolt's 10s write timeout; server connectivity loss partway through the multi-statement transaction.","solutions":["Verify all wisp aux tables exist with the expected schema and run migrations if they don't","Retry the delete — the transaction is atomic, so a retry after transient failure is safe","Reduce batch size or speed up Dolt (disk, indexes on aux table id columns) if write timeouts are the cause","Check the wrapped error chain for the specific aux table/driver error and fix it directly"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: verify expected aux tables exist before deleting\nfor _, tbl := range []string{\"wisp_labels\", \"wisp_events\"} {\n    var one int\n    if err := db.QueryRowContext(ctx,\n        \"SELECT 1 FROM information_schema.tables WHERE table_name = ?\", tbl).Scan(&one); err != nil {\n        return fmt.Errorf(\"aux table %s missing: %w\", tbl, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"_, err := store.DeleteWisps(ctx, ids)\nif err != nil && strings.Contains(err.Error(), \"delete wisp aux rows\") {\n    // aux cleanup failed: whole batch rolled back; run migrations or fix schema, then retry\n    log.Printf(\"aux row cleanup failed: %v\", err)\n    return err\n}","preventionTips":["Run all schema migrations after upgrading bd or the storage layer","Ensure foreign keys / cascades on aux tables are defined as expected by the schema","Keep batches small so aux-table deletes fit within Dolt's 10s write timeout","Index aux tables on the wisp id column to keep deletes fast"],"tags":["dolt","sql","transaction","schema"],"backgroundTag":"wisp-aux-row-delete-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}