rust-lang/cargo · error · anyhow::Error
`lints.{tool}.{name}` is not valid lint name; try `lints.{pr
Error message
`lints.{tool}.{name}` is not valid lint name; try `lints.{prefix}.{suffix}` What it means
Thrown during lint-table validation at src/workspace/parser/mod.rs:2727. If a lint name contains `::` and its first segment equals the tool name (e.g. `[lints.rust] rust::foo = ...` → prefix "rust" == tool "rust"), cargo treats it as a redundant/misplaced qualifier and suggests dropping the prefix by rewriting it as `lints.{prefix}.{suffix}` (i.e. `lints.rust.foo`).
Source
Thrown at src/workspace/parser/mod.rs:2727
for (name, config) in lints {
let normalized = name.replace('-', "_");
if name.contains('-') {
warnings.push(format!(
"`lints.{tool}.{name}` is deprecated in favor of \
`lints.{tool}.{normalized}` and will not work in a \
future edition"
));
}
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);View on GitHub (pinned to 0e07a15537)
Solutions
- Remove the redundant `tool::` prefix: under `[lints.rust]` write `foo = "warn"` instead of `rust::foo = "warn"`.
- Use the bare lint name that matches the table's tool.
Example fix
# before [lints.rust] rust::doc_markdown = "warn" # after [lints.rust] doc_markdown = "warn"
Defensive patterns
Strategy: validation
Validate before calling
for (name, _) in lints_for_tool {
if let Some((prefix, _suffix)) = name.split_once("::") {
if prefix == tool {
return Err(format!("lint {name} redundantly repeats tool {tool}"));
}
}
} Prevention
- Don't repeat the tool as a `::` prefix inside its own `[lints.<tool>]` table.
- Use bare lint names that match the table's tool.
When it happens
Trigger: Writing `[lints.rust] rust::doc_markdown = "warn"` or `[lints.cargo] cargo::... ` — the lint key redundantly repeats the tool as a `::` prefix.
Common situations: Copy-pasting the fully-qualified rustc lint name (`rust::xxx`) directly into the `[lints.rust]` table; tooling that emits group-qualified names.
Related errors
- `lints.{tool}.{name}` is not a valid lint name
- the crate `{}` depends on crate `{}` multiple times with dif
- Use of `default_features` in `{key}` is unsupported, please
- cannot override `workspace.lints` in `lints`, either remove
- `{old_path}` is unsupported as of the 2024 edition; instead
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/1a153f1230c7cb09.json.
Report an issue: GitHub.