{"id":"24159c136cfc8164","repo":"BurntSushi/ripgrep","slug":"the-literal-is-not-allowed-in-a-regex","errorCode":null,"errorMessage":"the literal {:?} is not allowed in a regex","messagePattern":"the literal (.+?) is not allowed in a regex","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/regex/src/strip.rs","lineNumber":60,"sourceCode":") -> Result<Hir, Error> {\n    if line_term.is_crlf() {\n        let expr1 = strip_from_match_ascii(expr, b'\\r')?;\n        strip_from_match_ascii(expr1, b'\\n')\n    } else {\n        strip_from_match_ascii(expr, line_term.as_byte())\n    }\n}\n\n/// The implementation of strip_from_match. The given byte must be ASCII.\n/// This function returns an error otherwise. It also returns an error if\n/// it couldn't remove `\\n` from the given regex without leaving an empty\n/// character class in its place.\nfn strip_from_match_ascii(expr: Hir, byte: u8) -> Result<Hir, Error> {\n    if !byte.is_ascii() {\n        return Err(Error::new(ErrorKind::InvalidLineTerminator(byte)));\n    }\n    let ch = char::from(byte);\n    let invalid = || Err(Error::new(ErrorKind::NotAllowed(ch.to_string())));\n    Ok(match expr.into_kind() {\n        HirKind::Empty => Hir::empty(),\n        HirKind::Literal(hir::Literal(lit)) => {\n            if lit.iter().find(|&&b| b == byte).is_some() {\n                return invalid();\n            }\n            Hir::literal(lit)\n        }\n        HirKind::Class(hir::Class::Unicode(mut cls)) => {\n            if cls.ranges().is_empty() {\n                return Ok(Hir::class(hir::Class::Unicode(cls)));\n            }\n            let remove = hir::ClassUnicode::new(Some(\n                hir::ClassUnicodeRange::new(ch, ch),\n            ));\n            cls.difference(&remove);\n            if cls.ranges().is_empty() {\n                return invalid();","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/BurntSushi/ripgrep/blob/3fce3b5bb0236da2df6d99672afb8a719642eca7/crates/regex/src/strip.rs#L42-L78","documentation":"strip_from_match removes the line-terminator byte from character classes where possible, but if a regex *must* match the line terminator as a literal (a bare literal, or a singleton/fully-stripped class), there is no safe rewrite and ErrorKind::NotAllowed(lit) is returned. The Display tells the user that literal is not allowed and (at the CLI layer) suggests enabling multiline mode (-U) so newlines can be matched.","triggerScenarios":"Building a non-multiline regex whose pattern contains the line terminator as a literal — e.g. searching with default line terminator \\n and a pattern like 'foo\\nbar', '\\n', '\\x0A', or a class that reduces to only \\n after stripping (e.g. [\\n]).","commonSituations":"rg 'foo\\nbar' without -U; a pattern intended to span lines written without enabling multiline mode; a generated pattern that embeds the record separator.","solutions":["Enable multiline mode: use the -U/--multiline flag (or (?m) / (?s) in the pattern) so the line terminator can be matched.","Remove the line-terminator literal from the pattern if you did not intend a multi-line match.","Change the configured line terminator to a byte not used in your pattern."],"exampleFix":"// before\n// $ rg 'foo\\nbar'   -> the literal '\\n' is not allowed in a regex\n\n// after\n// $ rg -U 'foo\\nbar' // multiline mode allows matching newlines","handlingStrategy":"validation","validationCode":"fn needs_multiline(pat: &str, lt: u8) -> bool {\n    pat.contains(lt as char) || pat.contains(&format!(\"\\\\x{:02X}\", lt))\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = build_regex(pat, line_term) {\n    eprintln!(\"{e} -- try enabling multiline mode (-U)\");\n}","preventionTips":["Enable multiline mode (-U / (?m)) whenever a pattern is meant to span lines.","Strip unintended line-terminator literals from generated patterns.","Choose a line terminator byte that does not appear in your patterns."],"tags":["regex","line-terminator","multiline","searcher"],"analyzedSha":"3fce3b5bb0236da2df6d99672afb8a719642eca7","analyzedAt":"2026-08-06T01:39:05.073Z","schemaVersion":2}