{"record":{"id":"808cdb8be5dc26cc","repo":"crowdsecurity/crowdsec","slug":"nil-stop-at","errorCode":null,"errorMessage":"nil stop_at","messagePattern":"nil stop_at","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":208,"sourceCode":"// it takes care of creating the new alert with the associated decisions, and it will as well deleted the \"older\" overlapping decisions:\n// 1st pull, you get decisions [1,2,3]. it inserts [1,2,3]\n// 2nd pull, you get decisions [1,2,3,4]. it inserts [1,2,3,4] and will try to delete [1,2,3,4] with a different alert ID and same origin\nfunc (c *Client) UpdateCommunityBlocklist(ctx context.Context, alertItem *models.Alert) (int, int, int, error) {\n\tif alertItem == nil {\n\t\treturn 0, 0, 0, errors.New(\"nil alert\")\n\t}\n\n\tif alertItem.StartAt == nil {\n\t\treturn 0, 0, 0, errors.New(\"nil start_at\")\n\t}\n\n\tstartAtTime, err := time.Parse(time.RFC3339, *alertItem.StartAt)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"start_at field time '%s': %w: %w\", *alertItem.StartAt, err, ParseTimeFail)\n\t}\n\n\tif alertItem.StopAt == nil {\n\t\treturn 0, 0, 0, errors.New(\"nil stop_at\")\n\t}\n\n\tstopAtTime, err := time.Parse(time.RFC3339, *alertItem.StopAt)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"stop_at field time '%s': %w: %w\", *alertItem.StopAt, err, ParseTimeFail)\n\t}\n\n\tts, err := time.Parse(time.RFC3339, *alertItem.StopAt)\n\tif err != nil {\n\t\tc.Log.Errorf(\"While parsing StartAt of item %s : %s\", *alertItem.StopAt, err)\n\n\t\tts = time.Now().UTC()\n\t}\n\n\talertB := c.Ent.Alert.\n\t\tCreate().\n\t\tSetScenario(*alertItem.Scenario).\n\t\tSetMessage(*alertItem.Message).","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L190-L226","documentation":"Guard in UpdateCommunityBlocklist: alert.StopAt (decision expiry timestamp) must be non-nil for the blocklist insertion and overlap-deletion logic; a nil StopAt means a malformed alert and is rejected.","triggerScenarios":"Thrown at pkg/database/alerts.go:208 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Populate StopAt on the alert before calling UpdateCommunityBlocklist","Check the upstream blocklist payload for a missing stop_at field"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}