{"record":{"id":"7b8d9660f84fb331","repo":"crowdsecurity/crowdsec","slug":"event-with-alert-id-d-w","errorCode":null,"errorMessage":"event with alert ID '%d': %w","messagePattern":"event with alert ID '(.+?)': %w","errorType":"exception","errorClass":"DeleteFail","httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":939,"sourceCode":"\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)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraph : %s\", err)\n\t\treturn fmt.Errorf(\"event with alert ID '%d': %w\", alertItem.ID, DeleteFail)\n\t}\n\n\t// delete the associated meta\n\t_, err = c.Ent.Meta.Delete().\n\t\tWhere(meta.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraph : %s\", err)\n\t\treturn fmt.Errorf(\"meta with alert ID '%d': %w\", alertItem.ID, DeleteFail)\n\t}\n\n\t// delete the associated decisions\n\t_, err = c.Ent.Decision.Delete().\n\t\tWhere(decision.HasOwnerWith(alert.IDEQ(alertItem.ID))).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraph : %s\", err)\n\t\treturn fmt.Errorf(\"decision with alert ID '%d': %w\", alertItem.ID, DeleteFail)\n\t}\n","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L921-L957","documentation":"DeleteAlertGraph removes all rows owned by one alert (events, meta, decisions, then the alert). This error means deleting the alert's Event rows failed, so the graph delete aborts with nothing else removed. The alert ID is embedded in the message and the cause is wrapped with the DeleteFail sentinel.","triggerScenarios":"DeleteAlertByID(ctx, id) -> DeleteAlertGraph: Event.Delete().Where(event.HasOwnerWith(alert.IDEQ(alertItem.ID))) fails due to DB unavailability, permission, lock, or cancelled context.","commonSituations":"cscli alerts delete on a machine whose DB connection has dropped; huge event tables causing long lock waits and timeouts; DB user without DELETE on events.","solutions":["Read the underlying error logged as 'DeleteAlertGraph : %s'","Verify connectivity and DELETE grants on the events table","Retry the delete for the same alert ID","Consider pruning events separately if the table is very large"],"exampleFix":"// before\nerr := client.DeleteAlertByID(ctx, alertID)\n// after\nif err := client.DeleteAlertByID(ctx, alertID); err != nil {\n    if errors.Is(err, entdb.DeleteFail) {\n        log.Errorf(\"failed deleting events for alert %d: %v\", alertID, err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"exists, err := client.Ent.Alert.Query().Where(alert.IDEQ(id)).Exist(ctx)\nif err != nil || !exists { return } // nothing to delete","typeGuard":null,"tryCatchPattern":"err := client.DeleteAlertByID(ctx, id)\nif err != nil && errors.Is(err, entdb.DeleteFail) {\n    // events stage failed; verify DB health before retry\n}","preventionTips":["Verify the DB user can DELETE from events","Prune old alerts regularly so event tables stay small","Avoid deleting alerts while bulk imports are running","Check 'DeleteAlertGraph' warnings in logs for early signs of DB trouble"],"tags":["database","delete","events"],"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"}