rust-lang/cargo · error
`lints. . ` is not a valid lint name
Error message
`lints.{tool}.{name}` is not a valid lint name What it means
Thrown during [lints] validation when a lint name contains '::' but the prefix does not match the tool name and is not a supported tool under 'rust'. This is the catch-all for unrecognized namespaced lint keys — e.g. [lints.rust] 'foo::bar' where 'foo' is unknown. Unlike the other two branches, no fix suggestion is offered because the intended location is unknown.
Solutions
- Remove the '::' and use the lint's bare name under the correct tool table (most rustc/clippy lints are bare names under [lints.rust]).
- Verify the lint exists in the target tool's lint list.
- If the lint is from a plugin, check whether [lints] supports it at all.
Example fix
# before [lints.rust] "clippy::needless_return" = "warn" # '::' form is invalid here # after [lints.rust] clippy_needless_return = "warn" # or configure clippy via [lints] with the correct bare name per docs
Defensive patterns
Strategy: validation
Validate before calling
fn lint_name_recognized(tool: &str, name: &str, supported: &[&str]) -> Result<(), String> {
if name.contains("::") {
let prefix = name.split_once("::").unwrap().0;
let known = prefix == tool || (tool == "rust" && supported.contains(&prefix));
if !known {
return Err(format!("unrecognized lint name `{name}` under [lints.{tool}]; remove `::` or verify the lint exists"));
}
}
Ok(())
} Type guard
fn is_valid_lint_key(tool: &str, name: &str, supported: &[&str]) -> bool {
if let Some((prefix, _)) = name.split_once("::") {
return prefix == tool || (tool == "rust" && supported.contains(&prefix));
}
true
} Prevention
- Avoid '::' in lint keys under [lints]; use the bare lint name.
- Verify each lint exists in the target tool before adding it.
- Remove unknown lint entries surfaced by CI manifest validation.
When it happens
Trigger: Writing a [lints] entry with a '::' in the name where the prefix is neither the current tool nor a recognized tool. For example [lints.rust] "unknown::lint" = "warn".
Common situations: A developer guesses a lint name that does not exist or misremembers the namespace. A typo in the prefix. Using a clippy lint under [lints.rust] without realizing clippy lints are bare names under [lints.rust] (clippy lints don't use '::').
Related errors
- `lints. . ` is not valid lint name; try `lints. .
- cannot override `workspace.lints` in `lints`, either remove…
- dependency ( ) specified without providing a local path…
- library target names cannot contain hyphens
- manifest is missing either a `[package]` or a `[workspace]`
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/45ee40860e16f1ee.
Report an issue: GitHub.
Appendix: source
Thrown at src/workspace/parser/mod.rs:2745
}
if let Some(existing) = seen_normalized.get(&normalized) {
warnings.push(format!(
"duplicate lint `{existing}` in `[lints.{tool}]`, \
conflicts with `{name}` and will not work in a future edition"
));
}
seen_normalized.insert(normalized.clone(), name.to_string());
if let Some((prefix, suffix)) = name.split_once("::") {
if tool == prefix {
anyhow::bail!(
"`lints.{tool}.{name}` is not valid lint name; try `lints.{prefix}.{suffix}`"
)
} else if tool == "rust" && supported.contains(&prefix) {
anyhow::bail!(
"`lints.{tool}.{name}` is not valid lint name; try `lints.{prefix}.{suffix}`"
)
} else {
anyhow::bail!("`lints.{tool}.{name}` is not a valid lint name")
}
} else if let Some(config) = config.config() {
for config_name in config.keys() {
// manually report unused manifest key warning since we collect all the "extra"
// keys and values inside the config table
let expected = EXPECTED_LINT_CONFIG.contains(&(tool, name, config_name));
if !expected {
let message =
format!("unused manifest key: `lints.{tool}.{name}.{config_name}`");
warnings.push(message);
}
}
}
}
}
Ok(())
}View on GitHub (pinned to 98a09e7e7d)