{"record":{"id":"3a573ceff5050aaa","repo":"rust-lang/rust-analyzer","slug":"failed-to-parse-pattern","errorCode":null,"errorMessage":"Failed to parse pattern: {}","messagePattern":"Failed to parse pattern: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ide-ssr/src/parsing.rs","lineNumber":260,"sourceCode":"        if let PatternElement::Placeholder(placeholder) = p {\n            if !defined_placeholders.contains(&placeholder.ident) {\n                undefined.push(placeholder.ident.to_string());\n            }\n            if !placeholder.constraints.is_empty() {\n                bail!(\"Replacement placeholders cannot have constraints\");\n            }\n        }\n    }\n    if !undefined.is_empty() {\n        bail!(\"Replacement contains undefined placeholders: {}\", undefined.join(\", \"));\n    }\n    Ok(())\n}\n\nfn tokenize(source: &str) -> Result<Vec<Token>, SsrError> {\n    let lexed = parser::LexedStr::new(parser::Edition::CURRENT, source);\n    if let Some((_, first_error)) = lexed.errors().next() {\n        bail!(\"Failed to parse pattern: {}\", first_error);\n    }\n    let mut tokens: Vec<Token> = Vec::new();\n    for i in 0..lexed.len() {\n        tokens.push(Token { kind: lexed.kind(i), text: lexed.text(i).into() });\n    }\n    Ok(tokens)\n}\n\nfn parse_placeholder(tokens: &mut std::vec::IntoIter<Token>) -> Result<Placeholder, SsrError> {\n    let mut name = None;\n    let mut constraints = Vec::new();\n    if let Some(token) = tokens.next() {\n        match token.kind {\n            SyntaxKind::IDENT => {\n                name = Some(token.text);\n            }\n            T!['{'] => {\n                let token =","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/ide-ssr/src/parsing.rs#L242-L278","documentation":"This error comes from the structural search/replace (SSR) pattern tokenizer. Before splitting the pattern into tokens, the pattern source is run through the rust-analyzer lexer; if the lexer reports any error (unbalanced quotes, bad characters, unterminated constructs), the whole pattern is rejected with this message carrying the underlying lexer error text. It fires early in parse_pattern via tokenize, so nothing is matched at all.","triggerScenarios":"Calling any ide-ssr API that parses a search or replace pattern (e.g. parse_pattern via SearchPattern::new) with source containing a lexing error, such as an unterminated string literal or invalid character, as detected by parser::LexedStr::new errors().","commonSituations":"Typing an SSR search pattern in the IDE's structural search box with a stray or unbalanced quote; programmatically building patterns with string interpolation that leaves broken syntax; copying a code snippet that includes an incomplete fragment.","solutions":["Read the embedded first_error text and fix the lexical problem (unterminated string/comment, illegal character) in the pattern","Verify the pattern is a complete, lexable Rust fragment before passing it to the SSR API","Escape special characters (quotes, braces) that were introduced by shell/string interpolation"],"exampleFix":"// before\nlet pattern = \"fn foo( -> u32\"; // unterminated paren/lexer garbage\n// after\nlet pattern = \"fn foo() -> u32\";","handlingStrategy":"validation","validationCode":"fn is_lexable(pattern: &str) -> bool {\n    let lexed = ide_ssr::parsing_lexer(pattern);\n    lexed.errors().next().is_none()\n}\n// reject patterns where is_lexable returns false before calling the SSR API","typeGuard":"fn is_valid_ssr_pattern(p: &str) -> bool {\n    !p.trim().is_empty() && p.chars().all(|c| !matches!(c, '\\u{0}'))\n}\n","tryCatchPattern":"match SearchPattern::new(&pattern) {\n    Ok(p) => apply(p),\n    Err(e) if e.message.starts_with(\"Failed to parse pattern\") => {\n        eprintln!(\"Invalid SSR pattern (lexer): {}\", e.message);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Test patterns in the IDE structural search box before scripting them","Check quotes and comments are balanced in the pattern","Escape quotes when embedding patterns in strings or shells","Keep patterns as complete Rust fragments"],"tags":["rust","parsing","lexer","ssr"],"backgroundTag":"ssr-pattern-parse-error","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}