crowdsecurity/crowdsec · error · DeleteFail
alert graph delete batch decisions: %w
Error message
alert graph delete batch decisions: %w
What it means
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.
Source
Thrown at pkg/database/alerts.go:918
_, err := c.Ent.Event.Delete().
Where(event.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraphBatch : %s", err)
return 0, fmt.Errorf("alert graph delete batch events: %w", DeleteFail)
}
_, err = c.Ent.Meta.Delete().
Where(meta.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraphBatch : %s", err)
return 0, fmt.Errorf("alert graph delete batch meta: %w", DeleteFail)
}
_, err = c.Ent.Decision.Delete().
Where(decision.HasOwnerWith(alert.IDIn(idList...))).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraphBatch : %s", err)
return 0, fmt.Errorf("alert graph delete batch decisions: %w", DeleteFail)
}
deleted, err := c.Ent.Alert.Delete().
Where(alert.IDIn(idList...)).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraphBatch : %s", err)
return deleted, fmt.Errorf("alert graph delete batch: %w", DeleteFail)
}
c.Log.Debug("Done batch delete alerts")
return deleted, nil
}
func (c *Client) DeleteAlertGraph(ctx context.Context, alertItem *ent.Alert) error {
// delete the associated events
_, err := c.Ent.Event.Delete().
Where(event.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)View on GitHub (pinned to 909b515798)
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
Example fix
// before
_, err := client.DeleteAlertGraphBatch(ctx, ids)
// after
if _, err := client.DeleteAlertGraphBatch(ctx, ids); err != nil {
if errors.Is(err, entdb.DeleteFail) {
log.Errorf("batch delete failed, check DB: %v", err)
// check connectivity / retry
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// check DB reachability before batch delete
if err := client.Ent.Decision.Query().Limit(1).Exec(ctx); err != nil {
return fmt.Errorf("database unavailable: %w", err)
}
if len(idList) == 0 { return nil } Try / catch
deleted, err := client.DeleteAlertGraphBatch(ctx, ids)
if err != nil {
if errors.Is(err, entdb.DeleteFail) {
// database-level failure: check connectivity/grants, retry
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- alert graph delete batch: %w
- hard delete decisions with provided filter: %w
- could not delete alerts: %w
- unable to delete
- while getting allowlist %s: %s
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/e9a9837e06b9f1b7.
Report an issue: GitHub.