{"record":{"id":"65f46eeb81480638","repo":"crowdsecurity/crowdsec","slug":"error-parsing-duration-s-of-s-w","errorCode":null,"errorMessage":"error parsing duration '%s' of %s: %w","messagePattern":"error parsing duration '(.+?)' of (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csprofiles/csprofiles.go","lineNumber":86,"sourceCode":"\t\t\tif runtimeDurationExpr, err = expr.Compile(profile.DurationExpr, exprhelpers.GetExprOptions(map[string]interface{}{\"Alert\": &models.Alert{}})...); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error compiling duration_expr of %s: %w\", profile.Name, err)\n\t\t\t}\n\n\t\t\truntime.RuntimeDurationExpr = runtimeDurationExpr\n\t\t}\n\n\t\tfor _, decision := range profile.Decisions {\n\t\t\tif runtime.RuntimeDurationExpr == nil {\n\t\t\t\tvar duration string\n\t\t\t\tif decision.Duration != nil {\n\t\t\t\t\tduration = *decision.Duration\n\t\t\t\t} else {\n\t\t\t\t\truntime.Logger.Warningf(\"No duration specified for %s, using default duration %s\", profile.Name, defaultDuration)\n\t\t\t\t\tduration = defaultDuration\n\t\t\t\t}\n\n\t\t\t\tif _, err := cstime.ParseDurationWithDays(duration); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"error parsing duration '%s' of %s: %w\", duration, profile.Name, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprofilesRuntime = append(profilesRuntime, runtime)\n\t}\n\n\treturn profilesRuntime, nil\n}\n\nfunc (profile *Runtime) GenerateDecisionFromProfile(alert *models.Alert) ([]*models.Decision, error) {\n\tvar decisions []*models.Decision\n\n\tfor _, refDecision := range profile.Cfg.Decisions {\n\t\tdecision := models.Decision{}\n\t\t/*the reference decision from profile is in simulated mode */\n\t\tif refDecision.Simulated != nil && *refDecision.Simulated {\n\t\t\tdecision.Simulated = new(bool)","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csprofiles/csprofiles.go#L68-L104","documentation":"When a profile's decision has a static `duration` string, NewProfile validates it with cstime.ParseDurationWithDays, which extends Go's time.ParseDuration to accept units like days (e.g. '4d'). If the string cannot be parsed (bad unit, empty, malformed number), NewProfile returns this error and configuration loading fails.","triggerScenarios":"A profile decision in configuration specifies a `duration` value that ParseDurationWithDays cannot parse: e.g. `duration: \"4days\"`, `duration: \"\"` when a default isn't set, `duration: \"4w\"` (weeks unsupported), or missing units like `duration: \"4\"`.","commonSituations":"Typos in profiles.yaml; copying durations from other tools that use different unit conventions (w for weeks, mo for months); forgetting units entirely; YAML quoting issues turning a valid value into something else.","solutions":["Use supported units: s, m, h, d (days) — e.g. '4h', '2d'.","Convert unsupported units manually (1w = 7d).","Ensure the value is a non-empty quoted string in YAML to avoid type coercion surprises.","If no duration is desired, rely on the profile default rather than leaving a malformed value."],"exampleFix":"// before (profiles.yaml)\nduration: 4w\n// after\nduration: 28d","handlingStrategy":"validation","validationCode":"if _, err := cstime.ParseDurationWithDays(cfgDuration); err != nil {\n    return fmt.Errorf(\"invalid profile duration %q: %w\", cfgDuration, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stick to supported units: s, m, h, d","Quote duration strings in YAML to avoid type coercion","Convert weeks/months to days manually (1w=7d)"],"tags":["config","duration","profile"],"backgroundTag":"invalid-duration-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"}