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

  1. Read the interpolated syntax_error in the message; it names the exact lexical problem.
  2. Supply a plain ASCII identifier matching [A-Za-z_][A-Za-z0-9_]* (or a well-formed lifetime for lifetimes).
  3. 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

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


AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03). Data as JSON: /api/errors/95a78768aec7d683. Report an issue: GitHub.