{"record":{"id":"c51a1b73640d96fe","repo":"crowdsecurity/crowdsec","slug":"nil-start-at","errorCode":null,"errorMessage":"nil start_at","messagePattern":"nil start_at","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":199,"sourceCode":"\t\treturn nil\n\t}); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn \"\", nil\n}\n\n// UpdateCommunityBlocklist is called to update either the community blocklist (or other lists the user subscribed to)\n// 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 {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L181-L217","documentation":"Guard in UpdateCommunityBlocklist: alert.StartAt (the decision validity start timestamp) must be set because it is used to compute overlapping decisions to delete; a nil StartAt would produce an invalid database row, so the alert is rejected.","triggerScenarios":"Thrown at pkg/database/alerts.go:199 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the alert model is fully populated (StartAt set) before calling UpdateCommunityBlocklist","Validate CAPI/PAPI payloads for a missing start_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-14T05:17:10.506Z"}