{"record":{"id":"055dcfaaa8a63692","repo":"crowdsecurity/crowdsec","slug":"stop-at-field-time-s-w-w","errorCode":null,"errorMessage":"stop_at field time '%s': %w: %w","messagePattern":"stop_at field time '(.+?)': %w: %w","errorType":"exception","errorClass":"ParseTimeFail","httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":213,"sourceCode":"\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).\n\t\tSetEventsCount(*alertItem.EventsCount).\n\t\tSetStartedAt(startAtTime).\n\t\tSetStoppedAt(stopAtTime).\n\t\tSetSourceScope(*alertItem.Source.Scope).\n\t\tSetSourceValue(*alertItem.Source.Value).","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L195-L231","documentation":"Same failure mode as the start_at check but for alertItem.StopAt: time.Parse(time.RFC3339, *alertItem.StopAt) failed while building the alert in UpdateCommunityBlocklist, so the call aborts with the value, the parse error, and the ParseTimeFail sentinel. Note the code below it parses StopAt a second time and merely falls back to time.Now() on failure — only the first parse is fatal.","triggerScenarios":"UpdateCommunityBlocklist (via SaveAlerts) receives an alert whose StopAt string is empty or not RFC3339-compatible (missing timezone offset, space instead of 'T', epoch seconds, etc.).","commonSituations":"Blocklist/CAPI pull with malformed stop_at from a subscribed list; scripts that construct models.Alert with Go's default time.String() output; timezone-less timestamps produced by third-party tooling.","solutions":["Fix the source to emit RFC3339 timestamps (UTC, e.g. '2026-09-06T12:00:00Z')","Normalize the timestamp in the caller before SaveAlerts","Use errors.Is(err, database.ParseTimeFail) to detect and skip/re-queue the offending alert"],"exampleFix":"// before\nalert.StopAt = ptr(startAt.Add(4*time.Hour).String())\n// after\nalert.StopAt = ptr(startAt.Add(4*time.Hour).UTC().Format(time.RFC3339))","handlingStrategy":"validation","validationCode":"if alert.StopAt == nil {\n    return errors.New(\"alert missing stop_at\")\n}\nif _, err := time.Parse(time.RFC3339, *alert.StopAt); err != nil {\n    return fmt.Errorf(\"invalid stop_at %q: %w\", *alert.StopAt, err)\n}","typeGuard":"func validRFC3339(s *string) bool {\n    if s == nil { return false }\n    _, err := time.Parse(time.RFC3339, *s)\n    return err == nil\n}","tryCatchPattern":"if _, _, _, err := db.UpdateCommunityBlocklist(ctx, alert); err != nil {\n    if errors.Is(err, database.ParseTimeFail) {\n        log.Warnf(\"skipping alert with bad stop_at: %v\", err)\n        return nil\n    }\n    return err\n}","preventionTips":["Emit stop_at/expiry in RFC3339 UTC from any custom list producer","Round-trip test serialized alerts (marshal/unmarshal) to catch format drift","Check errors.Is(err, ParseTimeFail) to skip single bad alerts instead of failing the batch"],"tags":["timestamp","rfc3339","capi"],"backgroundTag":"invalid-date-format","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"}