{"record":{"id":"e9a9837e06b9f1b7","repo":"crowdsecurity/crowdsec","slug":"alert-graph-delete-batch-decisions-w","errorCode":null,"errorMessage":"alert graph delete batch decisions: %w","messagePattern":"alert graph delete batch decisions: %w","errorType":"exception","errorClass":"DeleteFail","httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":918,"sourceCode":"\t_, err := c.Ent.Event.Delete().\n\t\tWhere(event.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraphBatch : %s\", err)\n\t\treturn 0, fmt.Errorf(\"alert graph delete batch events: %w\", DeleteFail)\n\t}\n\n\t_, err = c.Ent.Meta.Delete().\n\t\tWhere(meta.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraphBatch : %s\", err)\n\t\treturn 0, fmt.Errorf(\"alert graph delete batch meta: %w\", DeleteFail)\n\t}\n\n\t_, err = c.Ent.Decision.Delete().\n\t\tWhere(decision.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraphBatch : %s\", err)\n\t\treturn 0, fmt.Errorf(\"alert graph delete batch decisions: %w\", DeleteFail)\n\t}\n\n\tdeleted, err := c.Ent.Alert.Delete().\n\t\tWhere(alert.IDIn(idList...)).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraphBatch : %s\", err)\n\t\treturn deleted, fmt.Errorf(\"alert graph delete batch: %w\", DeleteFail)\n\t}\n\n\tc.Log.Debug(\"Done batch delete alerts\")\n\n\treturn deleted, nil\n}\n\nfunc (c *Client) DeleteAlertGraph(ctx context.Context, alertItem *ent.Alert) error {\n\t// delete the associated events\n\t_, err := c.Ent.Event.Delete().\n\t\tWhere(event.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L900-L936","documentation":"DeleteAlertGraphBatch deletes decisions belonging to the alerts in the batch, then the alerts themselves. This error means the ent ORM bulk DELETE of decisions (via the alert owner edge) failed against the database, so the batch delete is aborted before any alert rows are removed. The message wraps the sentinel DeleteFail, so it signals a database-level delete failure rather than a caller mistake.","triggerScenarios":"c.DeleteAlertGraphBatch(ctx, idList) is called and the ent query Decision.Delete().Where(decision.HasOwnerWith(alert.IDIn(idList...))) fails: DB connection down/timeout, table locked, permission denied on the decisions table, or context cancelled mid-query.","commonSituations":"Database restarted or unreachable during alert cleanup; LAPI delete-batch API call (DELETE /alerts) hitting a DB with connection-pool exhaustion; migration drift leaving the decisions/alerts FK edges in an unexpected state.","solutions":["Check database connectivity and logs (the raw error is logged via c.Log.Warningf as 'DeleteAlertGraphBatch')","Verify the DB user has DELETE privileges on the decisions table","Retry the batch delete; partial state may need the single-alert DeleteAlertByID path","If context timeouts are the cause, increase the request/context deadline"],"exampleFix":"// before\n_, err := client.DeleteAlertGraphBatch(ctx, ids)\n// after\nif _, err := client.DeleteAlertGraphBatch(ctx, ids); err != nil {\n    if errors.Is(err, entdb.DeleteFail) {\n        log.Errorf(\"batch delete failed, check DB: %v\", err)\n        // check connectivity / retry\n    }\n}","handlingStrategy":"try-catch","validationCode":"// check DB reachability before batch delete\nif err := client.Ent.Decision.Query().Limit(1).Exec(ctx); err != nil {\n    return fmt.Errorf(\"database unavailable: %w\", err)\n}\nif len(idList) == 0 { return nil }","typeGuard":null,"tryCatchPattern":"deleted, err := client.DeleteAlertGraphBatch(ctx, ids)\nif err != nil {\n    if errors.Is(err, entdb.DeleteFail) {\n        // database-level failure: check connectivity/grants, retry\n    }\n    return err\n}","preventionTips":["Check DB connectivity before large batch operations","Grant DELETE privileges on alerts and decisions to the crowdsec DB user","Keep batch sizes moderate to avoid long lock holds","Monitor the warning logs for 'DeleteAlertGraphBatch' to catch recurring DB issues"],"tags":["database","delete","ent"],"backgroundTag":"database-write-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}