{"record":{"id":"f1cb4f8540715e03","repo":"crowdsecurity/crowdsec","slug":"nil-alert","errorCode":null,"errorMessage":"nil alert","messagePattern":"nil alert","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":195,"sourceCode":"\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"creating alert decisions: %w\", err)\n\t\t}\n\t\tdecisions = append(decisions, ret...)\n\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)","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L177-L213","documentation":"Generic guard in UpdateCommunityBlocklist: the function requires a non-nil *models.Alert to insert into the database; a nil alert pointer was passed by SaveAlerts, indicating a programming error upstream, so it fails fast instead of panicking.","triggerScenarios":"Thrown at pkg/database/alerts.go:195 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the caller to pass a non-nil alert item","Add a nil check before constructing the blocklist update in tests or wrappers"],"exampleFix":null,"handlingStrategy":"type-guard","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"}