{"record":{"id":"f14f12fd1806e6bb","repo":"rust-lang/rust-analyzer","slug":"unknown-node-kind","errorCode":null,"errorMessage":"Unknown node kind '{}'","messagePattern":"Unknown node kind '(.+?)'","errorType":"validation","errorClass":"SsrError","httpStatus":null,"severity":"error","filePath":"crates/ide-ssr/src/parsing.rs","lineNumber":347,"sourceCode":"        x => bail!(\"Unsupported constraint type '{}'\", x),\n    }\n}\n\nfn expect_token(tokens: &mut std::vec::IntoIter<Token>, expected: &str) -> Result<(), SsrError> {\n    if let Some(t) = tokens.next() {\n        if t.text == expected {\n            return Ok(());\n        }\n        bail!(\"Expected {} found {}\", expected, t.text);\n    }\n    bail!(\"Expected {} found end of stream\", expected);\n}\n\nimpl NodeKind {\n    fn from(name: &SmolStr) -> Result<NodeKind, SsrError> {\n        Ok(match name.as_str() {\n            \"literal\" => NodeKind::Literal,\n            _ => bail!(\"Unknown node kind '{}'\", name),\n        })\n    }\n}\n\nimpl Placeholder {\n    fn new(name: SmolStr, constraints: Vec<Constraint>) -> Self {\n        Self {\n            stand_in_name: format!(\"__placeholder_{name}\"),\n            constraints,\n            ident: Var(name.to_string()),\n        }\n    }\n}\n\nimpl Display for Var {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"${}\", self.0)\n    }","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/ide-ssr/src/parsing.rs#L329-L365","documentation":"NodeKind::from converts a kind-constraint name into a NodeKind enum; in this codebase the only accepted name is \"literal\". Any other identifier passed to kind(...) triggers this error naming the unknown kind. This runs after the ident check in parse_constraint, so the syntax was valid but the vocabulary was not.","triggerScenarios":"Writing kind(node), kind(expr), kind(anything) — any ident other than literal — in an SSR placeholder constraint.","commonSituations":"Guessing at supported node kinds from rust-analyzer's broader SyntaxKind names; porting patterns from other tools with richer kind vocabularies; case mistakes such as kind(Literal).","solutions":["Use kind(literal), the only supported node kind","Wrap a negative case with not(): not(kind(literal)) to express 'anything but literal'","Check the SSR documentation for currently supported constraint kinds before extending patterns"],"exampleFix":"// before\nlet pattern = \"$x:kind(expr)\";\n// after\nlet pattern = \"$x:kind(literal)\";","handlingStrategy":"validation","validationCode":"const KNOWN_NODE_KINDS: &[&str] = &[\"literal\"];\nfn all_kind_names_known(p: &str) -> bool {\n    p.match_indices(\"kind(\")\n        .filter_map(|(i, _)| {\n            let rest = &p[i + 5..];\n            let end = rest.find(')')?;\n            Some(rest[..end].trim().to_string())\n        })\n        .all(|name| KNOWN_NODE_KINDS.contains(&name.as_str()))\n}\n","typeGuard":null,"tryCatchPattern":"match parse_pattern(pattern) {\n    Ok(p) => use_pattern(p),\n    Err(e) if e.message.contains(\"Unknown node kind\") => {\n        eprintln!(\"Only 'literal' is a supported kind in this SSR version\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use only documented kind names (currently 'literal')","Match case exactly (lowercase 'literal')","Do not assume rust-analyzer SyntaxKind names work in constraints","Verify constraint vocabulary against the SSR version in use"],"tags":["rust","parsing","ssr","constraints"],"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"}