crowdsecurity/crowdsec · error · DeleteFail
decision with alert ID '%d': %w
Error message
decision with alert ID '%d': %w
What it means
DeleteAlertGraph deletes the alert's decisions after events and meta. This error means the Decision DELETE failed, leaving events/meta already removed but decisions and the alert intact. Wraps the DeleteFail sentinel.
Source
Thrown at pkg/database/alerts.go:955
if err != nil {
c.Log.Warningf("DeleteAlertGraph : %s", err)
return fmt.Errorf("event with alert ID '%d': %w", alertItem.ID, DeleteFail)
}
// delete the associated meta
_, err = c.Ent.Meta.Delete().
Where(meta.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraph : %s", err)
return fmt.Errorf("meta with alert ID '%d': %w", alertItem.ID, DeleteFail)
}
// delete the associated decisions
_, err = c.Ent.Decision.Delete().
Where(decision.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraph : %s", err)
return fmt.Errorf("decision with alert ID '%d': %w", alertItem.ID, DeleteFail)
}
// delete the alert
err = c.Ent.Alert.DeleteOne(alertItem).Exec(ctx)
if err != nil {
c.Log.Warningf("DeleteAlertGraph : %s", err)
return fmt.Errorf("alert with ID '%d': %w", alertItem.ID, DeleteFail)
}
return nil
}
func (c *Client) DeleteAlertByID(ctx context.Context, id int) error {
alertItem, err := c.Ent.Alert.Query().Where(alert.IDEQ(id)).Only(ctx)
if err != nil {
return err
}
View on GitHub (pinned to 909b515798)
Solutions
- Check the 'DeleteAlertGraph : %s' warning for the root cause
- Retry DeleteAlertByID; the operation is safe to re-run
- Check for lock contention with active bouncer queries on decisions
- Verify DB user DELETE grants on decisions
Defensive patterns
Strategy: try-catch
Validate before calling
// decisions may be actively read by bouncers; check DB lock pressure first
n, err := client.Ent.Decision.Query().Where(decision.HasOwnerWith(alert.IDEQ(id))).Count(ctx)
if err != nil { /* DB unhealthy, skip delete */ } Try / catch
err := client.DeleteAlertByID(ctx, id)
if err != nil && errors.Is(err, entdb.DeleteFail) {
// decisions stage failed; check for bouncer read contention
} Prevention
- Schedule alert cleanup away from peak bouncer query times
- Ensure DELETE grants on decisions
- Check for long-running transactions blocking decisions
- Retry once before escalating
When it happens
Trigger: DeleteAlertByID(ctx, id) -> DeleteAlertGraph: Decision.Delete().Where(decision.HasOwnerWith(alert.IDEQ(alertItem.ID))) fails — DB unavailable, FK/lock issues from an active bouncer reading decisions, or missing grants.
Common situations: Lock contention because bouncers continuously SELECT from decisions while LAPI deletes; DB connection loss; migration mismatch on the decisions table.
Related errors
- unable to delete
- while getting decision: %w
- unable to expire decisions %+v: %w
- decision duration '%+v': %w: %w
- alert graph delete batch events: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/93e96d241d1caa9f.
Report an issue: GitHub.