diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index 74e7b2f8387..cd041000944 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -275,9 +275,25 @@ func (st DBstore) ListAlertRules(ctx context.Context, query *ngmodels.ListAlertR q = q.Asc("namespace_uid", "rule_group", "rule_group_idx", "id") alertRules := make([]*ngmodels.AlertRule, 0) - if err := q.Find(&alertRules); err != nil { + rule := new(ngmodels.AlertRule) + rows, err := q.Rows(rule) + if err != nil { return err } + defer func() { + _ = rows.Close() + }() + + // Deserialize each rule separately in case any of them contain invalid JSON. + for rows.Next() { + rule := new(ngmodels.AlertRule) + err = rows.Scan(rule) + if err != nil { + st.Logger.Error("Invalid rule found in DB store, ignoring it", "func", "ListAlertRules", "error", err) + continue + } + alertRules = append(alertRules, rule) + } query.Result = alertRules return nil @@ -455,9 +471,26 @@ func (st DBstore) GetAlertRulesForScheduling(ctx context.Context, query *ngmodel alertRulesSql += " WHERE " + filter } - if err := sess.SQL(alertRulesSql, args...).Find(&rules); err != nil { + rule := new(ngmodels.AlertRule) + rows, err := sess.SQL(alertRulesSql, args...).Rows(rule) + if err != nil { return fmt.Errorf("failed to fetch alert rules: %w", err) } + defer func() { + _ = rows.Close() + }() + + // Deserialize each rule separately in case any of them contain invalid JSON. + for rows.Next() { + rule := new(ngmodels.AlertRule) + err = rows.Scan(rule) + if err != nil { + st.Logger.Error("Invalid rule found in DB store, ignoring it", "func", "GetAlertRulesForScheduling", "error", err) + continue + } + rules = append(rules, rule) + } + query.ResultRules = rules if query.PopulateFolders { if err := sess.SQL(foldersSql, args...).Find(&folders); err != nil {