{"record":{"id":"b02140122f43c24f","repo":"kataras/iris","slug":"redirect-match-status-code-digits-s-d-c","errorCode":null,"errorMessage":"redirect match: status code digits: %s [%d:%c]","messagePattern":"redirect match: status code digits: (.+?) \\[(.+?):%c\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/rewrite/rewrite.go","lineNumber":291,"sourceCode":"\t\tif match := r.pattern.ReplaceAllString(src, r.target); match != \"\" {\n\t\t\treturn match, true\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n\nfunc parseRedirectMatchLine(s string) (*redirectMatch, error) {\n\tparts := strings.Split(strings.TrimSpace(s), \" \")\n\tif len(parts) != 3 {\n\t\treturn nil, fmt.Errorf(\"redirect match: invalid line: %s\", s)\n\t}\n\n\tcodeStr, pattern, target := parts[0], parts[1], parts[2]\n\n\tfor i, ch := range codeStr {\n\t\tif !isDigit(ch) {\n\t\t\treturn nil, fmt.Errorf(\"redirect match: status code digits: %s [%d:%c]\", codeStr, i, ch)\n\t\t}\n\t}\n\n\tcode, err := strconv.Atoi(codeStr)\n\tif err != nil {\n\t\t// this should not happen, we check abt digit\n\t\t// and correctly position the error too but handle it.\n\t\treturn nil, fmt.Errorf(\"redirect match: status code digits: %s: %v\", codeStr, err)\n\t}\n\n\tregex := regexp.MustCompile(pattern)\n\tif regex.MatchString(target) {\n\t\treturn nil, fmt.Errorf(\"redirect match: loop detected: pattern: %s vs target: %s\", pattern, target)\n\t}\n\n\tv := &redirectMatch{\n\t\tcode:              code,\n\t\tpattern:           regex,","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/middleware/rewrite/rewrite.go#L273-L309","documentation":"parseRedirectMatchLine validates redirect rewrite rules of the form 'CODE PATTERN TARGET'. Every character of the status-code field must be a digit; when a non-digit is found at index i, the parser rejects the whole line with this error, naming the bad character and its position. This prevents a malformed code like '30x' from silently becoming code 30 or 0.","triggerScenarios":"Registering a Rewrite redirect rule via rewrite.New (or RedirectMatch directive) where the first whitespace-separated field is not purely numeric, e.g. '30x /old /new' or 'redirect /old /new' (missing the code).","commonSituations":"Typo in a redirect config line, copying an Apache-style RedirectMatch line without adjusting the syntax, or a rule line where the code field was accidentally omitted so pattern/target shift left.","solutions":["Make the first field of the redirect line a pure-digit status code (e.g. 301, 302, 307, 308).","Check that the line has exactly three whitespace-separated fields: code, pattern, target — a missing field shifts values left.","If porting from Apache/nginx configs, rewrite the directive to this library's 'CODE PATTERN TARGET' format.","Validate the code string with a regexp like ^\\d{3}$ before calling New in tests or tooling."],"exampleFix":"// before\nrewrite.New([]rewrite.RedirectMatchLine{\"30x /old(.*) /new/$1\"})\n// after\nrewrite.New([]rewrite.RedirectMatchLine{\"301 /old(.*) /new/$1\"})","handlingStrategy":"validation","validationCode":"var codeRe = regexp.MustCompile(`^\\d+$`)\nif !codeRe.MatchString(strings.Fields(line)[0]) {\n    return fmt.Errorf(\"invalid redirect line %q: code must be digits\", line)\n}","typeGuard":null,"tryCatchPattern":"if err := rewrite.New(lines); err != nil {\n    var perr *parseError\n    if errors.As(err, &perr) { /* fix config line */ }\n    log.Fatalf(\"redirect config invalid: %v\", err)\n}","preventionTips":["Keep every redirect line as exactly three fields: digits, pattern, target.","Add a config lint/test that parses all redirect lines at startup in CI.","When porting Apache RedirectMatch rules, rewrite them to this format first."],"tags":["config","rewrite","validation"],"backgroundTag":"invalid-status-code","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}