linebender/druid · error
Duplicate attribute
Error message
Duplicate attribute
What it means
While parsing #[lens(...)] field attributes, the lens(ignore) option may appear at most once per item. Specifying lens(ignore) (or repeating the ignore path) twice triggers this compile-time error at the second occurrence's span.
Solutions
- Remove the duplicate lens(ignore) — one occurrence is enough to exclude the field from the lens.
- Review the field's attribute list and deduplicate options.
- If you meant to ignore two different fields, put one #[lens(ignore)] on each field.
Example fix
// before #[lens(ignore, ignore)] screen: ScreenId, // after #[lens(ignore)] screen: ScreenId,
Defensive patterns
Strategy: validation
Validate before calling
// Deduplicate lens options before compiling:
fn check_no_dup_ignore(attrs: &[&str]) -> Result<(), String> {
let count = attrs.iter().filter(|a| **a == "ignore").count();
if count > 1 { Err("lens(ignore) specified more than once".into()) } else { Ok(()) }
} Prevention
- Write lens(ignore) at most once per field.
- After merge conflicts, re-read each field's attribute list for duplicates.
- One ignore directive excludes the field fully; repetition adds nothing.
When it happens
Trigger: Writing #[lens(ignore, ignore)] on the same field, or repeating the ignore path in two different nested forms within one attribute list.
Common situations: Merging fields or copy-pasting attribute lines when refactoring struct definitions, resulting in a duplicated ignore directive.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Unknown attribute
- Expected attribute list (the form #[data(one, two)])
- Expected attribute list (the form #[lens(one, two)])
- expected str, found... something else
- Data implementations cannot be derived from unions
AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10).
Data as JSON: /api/errors/d16d8918aef27deb.
Report an issue: GitHub.
Appendix: source
Thrown at druid-derive/src/attr.rs:222
let mut ignore = false;
let mut lens_name_override = None;
for attr in field.attrs.iter() {
if attr.path.is_ident(BASE_DRUID_DEPRECATED_ATTR_PATH) {
panic!(
"The 'druid' attribute has been replaced with separate \
'lens' and 'data' attributes.",
);
} else if attr.path.is_ident(BASE_LENS_ATTR_PATH) {
match attr.parse_meta()? {
Meta::List(meta) => {
for nested in meta.nested.iter() {
match nested {
NestedMeta::Meta(Meta::Path(path))
if path.is_ident(IGNORE_ATTR_PATH) =>
{
if ignore {
return Err(Error::new(
nested.span(),
"Duplicate attribute",
));
}
ignore = true;
}
NestedMeta::Meta(Meta::NameValue(meta))
if meta.path.is_ident(LENS_NAME_OVERRIDE_ATTR_PATH) =>
{
if lens_name_override.is_some() {
return Err(Error::new(meta.span(), "Duplicate attribute"));
}
let ident = parse_lit_into_ident(&meta.lit)?;
lens_name_override = Some(ident);
}
other => return Err(Error::new(other.span(), "Unknown attribute")),
}View on GitHub (pinned to 0f8b1195e4)