crowdsecurity/crowdsec · error · DeleteFail

meta with alert ID '%d': %w

Error message

meta with alert ID '%d': %w

What it means

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.

Source

Thrown at pkg/database/alerts.go:947

	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)
	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

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the 'DeleteAlertGraph : %s' warning log for the root DB error
  2. Retry DeleteAlertByID for the alert ID (idempotent: already-deleted rows simply don't match)
  3. Verify DELETE permissions on meta
  4. Investigate lock contention if deletes run concurrently
Defensive patterns

Strategy: try-catch

Validate before calling

exists, _ := client.Ent.Meta.Query().Where(meta.HasOwnerWith(alert.IDEQ(id))).Exist(ctx)
_ = exists // if false, meta stage is trivially skippable

Try / catch

err := client.DeleteAlertByID(ctx, id)
if err != nil && errors.Is(err, entdb.DeleteFail) {
    // stage-specific failure; safe to retry, earlier stages are idempotent
}

Prevention

When it happens

Trigger: DeleteAlertByID(ctx, id) -> DeleteAlertGraph: Meta.Delete().Where(meta.HasOwnerWith(alert.IDEQ(alertItem.ID))) fails — DB error, lock timeout, missing grant, or context cancelled.

Common situations: Same as the events-stage failure: DB connection dropped mid-delete, lock contention from concurrent bulk deletions, insufficient privileges on the meta table.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/43b7e21a57034985. Report an issue: GitHub.