{"record":{"id":"95da1f60feb5c373","repo":"crowdsecurity/crowdsec","slug":"failed-to-count-alerts-per-scenario-w","errorCode":null,"errorMessage":"failed to count alerts per scenario: %w","messagePattern":"failed to count alerts per scenario: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":782,"sourceCode":"\treturn alertIDs, nil\n}\n\nfunc (c *Client) AlertsCountPerScenario(ctx context.Context, filter map[string][]string) (map[string]int, error) {\n\tvar res []struct {\n\t\tScenario string\n\t\tCount    int\n\t}\n\n\tquery := c.Ent.Alert.Query()\n\n\tquery, err := applyAlertFilter(query, filter)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to build alert request: %w\", err)\n\t}\n\n\terr = query.GroupBy(alert.FieldScenario).Aggregate(ent.Count()).Scan(ctx, &res)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to count alerts per scenario: %w\", err)\n\t}\n\n\tcounts := make(map[string]int)\n\n\tfor _, r := range res {\n\t\tcounts[r.Scenario] = r.Count\n\t}\n\n\treturn counts, nil\n}\n\nfunc (c *Client) TotalAlerts(ctx context.Context) (int, error) {\n\treturn c.Ent.Alert.Query().Count(ctx)\n}\n\nfunc (c *Client) QueryAlertWithFilter(ctx context.Context, filter map[string][]string) ([]*ent.Alert, error) {\n\tsort := \"DESC\" // we sort by desc by default\n","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L764-L800","documentation":"The ent GROUP BY (scenario) + COUNT aggregation query backing AlertsCountPerScenario failed at Scan time. The alert filter itself was built successfully; the failure is at DB execution — connection loss, timeout, or SQL error from the underlying database.","triggerScenarios":"The ent Scan call fails: DB unreachable, driver error, or context cancelled while aggregating alerts per scenario.","commonSituations":"Large alerts table making the GROUP BY slow enough to hit a context deadline; DB migration in progress; connection pool exhaustion under concurrent LAPI queries.","solutions":["Inspect the wrapped error for the driver-level cause","Retry with a narrower time filter to reduce scan size","Check DB health and slow-query logs","Increase the caller's context timeout for large tables"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"counts, err := db.AlertsCountPerScenario(ctx, filter)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) {\n        // retry with longer timeout / narrower filter\n    }\n    return err\n}","preventionTips":["Add a since filter to bound the aggregation","Schedule heavy per-scenario counts off-peak","Keep the alerts table pruned"],"tags":["database","aggregate","query"],"backgroundTag":"sql-query-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}