{"record":{"id":"8043871701adb326","repo":"crowdsecurity/crowdsec","slug":"empty-time-now-s","errorCode":null,"errorMessage":"empty time now() - %s","messagePattern":"empty time now\\(\\) - (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alertfilter.go","lineNumber":54,"sourceCode":"\t\tscope = types.Ip\n\t} else if strings.ToLower(scope) == \"range\" {\n\t\tscope = types.Range\n\t}\n\n\t*predicates = append(*predicates, alert.SourceScopeEQ(scope))\n}\n\nfunc handleTimeFilters(param, value string, predicates *[]predicate.Alert) error {\n\t// crowsdec now always sends duration without days, but we allow them for\n\t// compatibility with other tools\n\tduration, err := cstime.ParseDurationWithDays(value)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"while parsing duration: %w\", err)\n\t}\n\n\ttimePoint := time.Now().UTC().Add(-duration)\n\tif timePoint.IsZero() {\n\t\treturn fmt.Errorf(\"empty time now() - %s\", timePoint.String())\n\t}\n\n\tswitch param {\n\tcase \"since\":\n\t\t*predicates = append(*predicates, alert.StartedAtGTE(timePoint))\n\tcase \"created_before\":\n\t\t*predicates = append(*predicates, alert.CreatedAtLTE(timePoint))\n\tcase \"until\":\n\t\t*predicates = append(*predicates, alert.StartedAtLTE(timePoint))\n\t}\n\n\treturn nil\n}\n\nfunc handleAlertIPv4Predicates(rng csnet.Range, contains bool, predicates *[]predicate.Alert) {\n\tif contains { // decision contains {start_ip,end_ip}\n\t\t*predicates = append(*predicates, alert.And(\n\t\t\talert.HasDecisionsWith(decision.StartIPLTE(rng.Start.Addr)),","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alertfilter.go#L36-L72","documentation":"Returned by handleTimeFilters when time.Now().UTC().Add(-duration) yields the zero time value. This is a defensive check; with real clock values it is practically unreachable but signals that the computed time point is unusable for a GTE/LTE predicate.","triggerScenarios":"The computed timePoint from now minus the parsed duration equals time.Time{} — only possible in degenerate conditions (clock anomalies, mocked zero clocks in tests).","commonSituations":"Test environments with a zero-valued mocked clock, or exotic time sources returning the zero time.","solutions":["Verify system clock is sane (date; timedatectl) — an absurdly wrong clock is the realistic trigger.","Remove any test/mocked clock returning zero time.Time{} and inject a realistic one.","Update crowdsec, as newer versions may have dropped or refined this check."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if time.Now().IsZero() {\n    return fmt.Errorf(\"system clock reports zero time; refusing to build filter\")\n}","typeGuard":null,"tryCatchPattern":"preds, err := alertPredicatesFromFilter(filter)\nif err != nil {\n    log.Warnf(\"time filter rejected: %v\", err)\n    return http.StatusBadRequest\n}","preventionTips":["Keep system clock synchronized (NTP/chrony)","In tests, never mock now() to return time.Time{}","Treat this error as an environment problem, not a data problem"],"tags":["go","time","lapi"],"backgroundTag":"internal-invariant-violation","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"}