rust-lang/rust-analyzer · error
Invalid name `{}`: {}
Error message
Invalid name `{}`: {} What it means
`IdentifierKind::classify` (crates/ide-db/src/rename.rs:833) rejects a proposed rename name that lexes as a single token but carries a parser syntax error. The token's associated error message (`syntax_error`) is interpolated into 'Invalid name `{}`: {}'. This is the generic malformed-token path of name validation.
Source
Thrown at crates/ide-db/src/rename.rs:833
impl IdentifierKind {
pub fn classify(edition: Edition, new_name: &str) -> Result<(Name, IdentifierKind)> {
match parser::LexedStr::single_token(edition, new_name) {
Some(res) => match res {
(SyntaxKind::IDENT, _) => Ok((Name::new_root(new_name), IdentifierKind::Ident)),
(T![_], _) => {
Ok((Name::new_symbol_root(sym::underscore), IdentifierKind::Underscore))
}
(SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => {
Ok((Name::new_lifetime(new_name), IdentifierKind::Lifetime))
}
_ if SyntaxKind::from_keyword(new_name, edition).is_some() => match new_name {
"self" => Ok((Name::new_root(new_name), IdentifierKind::LowercaseSelf)),
"crate" | "super" | "Self" => {
bail!("Invalid name `{}`: cannot rename to a keyword", new_name)
}
_ => Ok((Name::new_root(new_name), IdentifierKind::Ident)),
},
(_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error),
(_, None) => bail!("Invalid name `{}`: not an identifier", new_name),
},
None => bail!("Invalid name `{}`: not an identifier", new_name),
}
}
}
View on GitHub (pinned to e8f7e90aa3)
Solutions
- Read the interpolated syntax_error in the message; it names the exact lexical problem.
- Supply a plain ASCII identifier matching [A-Za-z_][A-Za-z0-9_]* (or a well-formed lifetime for lifetimes).
- For raw identifiers, use the complete form `r#name`, never a bare `r#` prefix.
Example fix
// before
{ "newName": "r#" }
// after
{ "newName": "r#type" } Defensive patterns
Strategy: validation
Validate before calling
fn validate_single_token(new_name: &str) -> Result<(), String> {
if new_name.starts_with("r#") && new_name.len() <= 2 {
return Err("raw identifier must be r# followed by a name".into());
}
Ok(())
} Type guard
fn looks_like_well_formed_token(s: &str) -> bool {
!s.is_empty() && !s.contains(char::is_whitespace)
&& !(s == "r#")
} Prevention
- Never send a bare `r#` prefix; always complete raw identifiers (r#name).
- Strip stray characters/whitespace from user input before issuing rename.
- Parse the interpolated syntax_error in the message for the exact lexical problem.
- Test scripted renames with realistic names, not placeholders like $name.
When it happens
Trigger: Renaming to a token the Rust lexer/parser rejects, e.g. an empty raw identifier `r#`, a malformed literal-as-name, or any single token with an attached lexical error; fires at the `(_, Some(syntax_error))` arm.
Common situations: Copy-pasting a name with stray characters; automated tooling passing a placeholder like `"$name"` or `"foo bar"` fragments that still tokenize; renaming to `r#` with no identifier after the raw prefix.
Related errors
- Invalid name `{}`: cannot rename to a keyword
- Cannot rename local to self outside of function
- Method already has a self parameter
- Only the first parameter may be renamed to self
- No file available to rename
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/95a78768aec7d683.
Report an issue: GitHub.