{"record":{"id":"12f45b0e3a35dec2","repo":"gohugoio/hugo","slug":"failed-to-compile-redirect-regexp-q-w","errorCode":null,"errorMessage":"failed to compile Redirect regexp %q: %w","messagePattern":"failed to compile Redirect regexp %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/commonConfig.go","lineNumber":277,"sourceCode":"\t}\n\tfor _, r := range s.Redirects {\n\t\tif r.From == \"\" && r.FromRe == \"\" {\n\t\t\treturn fmt.Errorf(\"redirects must have either From or FromRe set\")\n\t\t}\n\t\trd := redirect{\n\t\t\theaders: make(map[string]glob.Glob),\n\t\t}\n\t\tif r.From != \"\" {\n\t\t\tg, err := glob.Compile(r.From)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect glob %q: %w\", r.From, err)\n\t\t\t}\n\t\t\trd.from = g\n\t\t}\n\t\tif r.FromRe != \"\" {\n\t\t\tre, err := regexp.Compile(r.FromRe)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect regexp %q: %w\", r.FromRe, err)\n\t\t\t}\n\t\t\trd.fromRe = re\n\t\t}\n\t\tfor k, v := range r.FromHeaders {\n\t\t\tg, err := glob.Compile(v)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect header glob %q: %w\", v, err)\n\t\t\t}\n\t\t\trd.headers[k] = g\n\t\t}\n\t\ts.compiledRedirects = append(s.compiledRedirects, rd)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {\n\tif s.compiledHeaders == nil {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/config/commonConfig.go#L259-L295","documentation":"Emitted by Server.CompileConfig when a redirect's `fromRe` regexp fails to compile via Go's regexp package. This is the regex-based matcher (alternative to glob `from`), used when you need capture groups for substitution in `to`.","triggerScenarios":"A `[[server.redirects]]` with `fromRe` set to an invalid Go regexp: unbalanced parens, invalid escape, unsupported syntax.","commonSituations":"Using PCRE-only syntax unsupported by Go RE2 (e.g. backreferences, lookahead); copy-pasting a regex from another language.","solutions":["Test `fromRe` with Go regexp semantics (RE2). No backreferences/lookahead.","Balance groups; escape metacharacters intended literally.","Use named groups or positional groups referenced as $1 in `to`."],"exampleFix":"# before (invalid RE2 lookahead)\n[[server.redirects]]\nfromRe = \"^/old/(?=sub).*\"\nto = \"/new\"\n\n# after\n[[server.redirects]]\nfromRe = \"^/old/(.*)\"\nto = \"/new/$1\"","handlingStrategy":"validation","validationCode":"python3 - <<'PY'\nimport tomllib,re\ncfg=tomllib.loads(open('hugo.toml').read())\nfor r in cfg.get('server',{}).get('redirects',[]):\n    fr=r.get('fromRe','')\n    if fr:\n        try: re.compile(fr)\n        except re.error as e: print(f\"bad fromRe {fr!r}: {e}\")\nprint(\"redirect regexps ok\")\nPY","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Go RE2 syntax for fromRe (no backreferences/lookahead).","Reference capture groups as $1, $2 in `to`.","Escape metacharacters intended literally."],"tags":["config","server","redirects","regexp"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}