{"record":{"id":"e70531b759a2bf12","repo":"crowdsecurity/crowdsec","slug":"invalid-user-agent-regex-for-bot-entry-s-in-s","errorCode":null,"errorMessage":"invalid user_agent regex for bot entry '%s' in %s: %w","messagePattern":"invalid user_agent regex for bot entry '(.+?)' in (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/exprhelpers/botfile.go","lineNumber":70,"sourceCode":"\tdec.DisallowUnknownFields()\n\n\tif err := dec.Decode(entry); err != nil {\n\t\treturn fmt.Errorf(\"failed to parse JSON line in %s: %w\", filename, err)\n\t}\n\n\tif entry.Name == \"\" {\n\t\treturn fmt.Errorf(\"missing mandatory 'name' field in %s: %s\", filename, line)\n\t}\n\n\tif len(entry.IPs)+len(entry.Ranges)+len(entry.RDNS) == 0 {\n\t\treturn fmt.Errorf(\"bot entry '%s' in %s has no identity verification (need at least one of ips/ranges/rdns)\", entry.Name, filename)\n\t}\n\n\tvar err error\n\n\tif entry.UserAgent != \"\" {\n\t\tif entry.uaRegex, err = compileBotRegex(entry.UserAgent); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid user_agent regex for bot entry '%s' in %s: %w\", entry.Name, filename, err)\n\t\t}\n\t}\n\n\tfor _, p := range entry.Paths {\n\t\tre, err := compileBotRegex(p)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid path regex '%s' for bot entry '%s' in %s: %w\", p, entry.Name, filename, err)\n\t\t}\n\n\t\tentry.pathRegexes = append(entry.pathRegexes, re)\n\t}\n\n\tentry.ipSet = make(map[netip.Addr]struct{}, len(entry.IPs))\n\n\tfor _, ip := range entry.IPs {\n\t\taddr, err := netip.ParseAddr(ip)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid IP '%s' for bot entry '%s' in %s: %w\", ip, entry.Name, filename, err)","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/exprhelpers/botfile.go#L52-L88","documentation":"botFileInit pre-compiles the optional user_agent field as a case-insensitive regular expression via compileBotRegex. This error is thrown when regexp.Compile rejects the pattern (unbalanced parens/brackets, dangling escape, invalid repetition, etc.). Compiling at load time catches bad regexes before any traffic is matched.","triggerScenarios":"A bots JSONL entry has a \"user_agent\" value that is not a valid Go RE2 regex, e.g. \"Mozilla*\" (invalid repetition), \"(bad\" (unbalanced group), or a trailing backslash. The wrapped error is the regexp/syntax parse error.","commonSituations":"Copying UA strings verbatim that contain regex metacharacters like +, (, ), ? without escaping; hand-written regex with a typo; converting patterns from PCRE with unsupported constructs like lookaheads (?=...) or backreferences, which RE2 rejects.","solutions":["Escape regex metacharacters in literal UA substrings, e.g. use \"Mozilla/5\\.0 \\(compatible\\)\" not \"Mozilla/5.0 (compatible)\".","Fix the syntax error reported by the wrapped regexp/syntax message (it names the offending position).","Replace PCRE-only constructs (lookaheads, lookbehinds, backreferences) with RE2-compatible patterns.","Simplify to a substring pattern if you do not need regex power: \"Googlebot\" matches anywhere (compile is case-insensitive).","Test the pattern first with Go: regexp.Compile(\"(?i)\" + pattern) in a scratch program."],"exampleFix":"// before\n{\"name\":\"chrome\",\"user_agent\":\"Chrome/(ver 1+2)\"}\n// after\n{\"name\":\"chrome\",\"user_agent\":\"Chrome/\\(ver 1\\+2\\)\"}","handlingStrategy":"validation","validationCode":"// compile-check the user_agent pattern exactly as the loader will\nif _, err := regexp.Compile(\"(?i)\" + uaPattern); err != nil {\n\t// reject before FileInit\n}\nvalid := err == nil","typeGuard":null,"tryCatchPattern":"if err := exprhelpers.FileInit(botFile, \"bots\"); err != nil {\n\tif strings.Contains(err.Error(), \"invalid user_agent regex\") {\n\t\tlog.Errorf(\"fix the UA pattern: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Escape regex metacharacters in literal UA text: use regexp.QuoteMeta for fixed substrings.","Stick to RE2: no lookaheads, lookbehinds, or backreferences.","Compile every pattern with regexp.Compile in CI before shipping the data file.","Start from simple substring patterns; add regex features only when needed."],"tags":["go","regex","validation","data-files"],"backgroundTag":"invalid-regex-pattern","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"}