{"record":{"id":"43b7e21a57034985","repo":"crowdsecurity/crowdsec","slug":"meta-with-alert-id-d-w","errorCode":null,"errorMessage":"meta with alert ID '%d': %w","messagePattern":"meta with alert ID '(.+?)': %w","errorType":"exception","errorClass":"DeleteFail","httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":947,"sourceCode":"\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\n\t// delete the alert\n\terr = c.Ent.Alert.DeleteOne(alertItem).Exec(ctx)\n\tif err != nil {\n\t\tc.Log.Warningf(\"DeleteAlertGraph : %s\", err)\n\t\treturn fmt.Errorf(\"alert with ID '%d': %w\", alertItem.ID, DeleteFail)\n\t}\n\n\treturn nil","sourceCodeStart":929,"sourceCodeEnd":965,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L929-L965","documentation":"DeleteAlertGraph deletes an alert's meta rows after events. This error means the Meta DELETE query failed; events may already be gone but meta, decisions and the alert remain. Wraps the DeleteFail sentinel.","triggerScenarios":"DeleteAlertByID(ctx, id) -> DeleteAlertGraph: Meta.Delete().Where(meta.HasOwnerWith(alert.IDEQ(alertItem.ID))) fails — DB error, lock timeout, missing grant, or context cancelled.","commonSituations":"Same as the events-stage failure: DB connection dropped mid-delete, lock contention from concurrent bulk deletions, insufficient privileges on the meta table.","solutions":["Check the 'DeleteAlertGraph : %s' warning log for the root DB error","Retry DeleteAlertByID for the alert ID (idempotent: already-deleted rows simply don't match)","Verify DELETE permissions on meta","Investigate lock contention if deletes run concurrently"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"exists, _ := client.Ent.Meta.Query().Where(meta.HasOwnerWith(alert.IDEQ(id))).Exist(ctx)\n_ = exists // if false, meta stage is trivially skippable","typeGuard":null,"tryCatchPattern":"err := client.DeleteAlertByID(ctx, id)\nif err != nil && errors.Is(err, entdb.DeleteFail) {\n    // stage-specific failure; safe to retry, earlier stages are idempotent\n}","preventionTips":["Grant DELETE on the meta table to the app DB user","Retry failed alert deletes — each stage filters by ID","Avoid concurrent bulk deletes on the same alert","Monitor DB lock wait metrics"],"tags":["database","delete","meta"],"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"}