linebender/druid · error
Unknown attribute
Error message
Unknown attribute
What it means
This error comes from druid-derive's parsing of helper attributes (e.g. #[data(...)]) during derive macro expansion. The derive expects only recognized nested attributes inside the helper attribute list; any other attribute path, name-value pair, or literal is rejected with "Unknown attribute". It is a compile-time proc-macro error pointing at the offending token's span.
Solutions
- Replace the unknown attribute with one supported by the derive (for #[data]: data(eq); for #[lens]: lens(name = "...") or lens(ignore)).
- Check the druid-derive documentation/version for the exact accepted attribute names — names changed between druid versions.
- Remove the stray attribute if it was intended for another derive macro, and place it on the correct item.
- If the attribute belongs to another derive on the same struct, ensure you are not putting it inside the wrong helper attribute list.
Example fix
// before
#[derive(Data)]
enum Msg {
#[data(ignore)]
A(i32),
}
// after
#[derive(Data)]
enum Msg {
#[data(eq)]
A(i32),
} Defensive patterns
Strategy: validation
Validate before calling
// Before expanding the derive, audit each helper attribute:
const DATA_ALLOWED: &[&str] = &["eq"];
fn validate_data_attr(meta: &str) -> Result<(), String> {
let inner = meta.strip_prefix("data(")?.strip_suffix(')')?;
inner.split(',').map(str::trim).try_for_each(|opt| {
if DATA_ALLOWED.contains(&opt) { Ok(()) } else { Err(format!("unknown data option: {}", opt)) }
})
} Prevention
- Only use documented options inside #[data(...)]: currently data(eq).
- Do not put foreign attributes (serde, etc.) inside the druid helper attribute list.
- Check the druid-derive source/docs for accepted attribute names when upgrading versions.
- Let the compiler point you at the exact span in the error message.
When it happens
Trigger: Writing an unrecognized entry inside #[data(...)] or #[lens(...)], such as #[data(foo)] or a typo like #[data(eq)] (correct form is data(eq)), or passing a name-value item where only path attributes are accepted.
Common situations: Typos in attribute names, copy-pasting attributes from other derive crates (serde-style attributes), misremembering the helper attribute syntax after a version change in druid-derive.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected attribute list (the form #[data(one, two)])
- Duplicate attribute
- 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/077d352e8b797760.
Report an issue: GitHub.
Appendix: source
Thrown at druid-derive/src/attr.rs:160
if let Some(nested) = meta.nested.first() {
match nested {
NestedMeta::Meta(Meta::Path(path))
if path.is_ident(IGNORE_ATTR_PATH) =>
{
data_attr = DataAttr::Ignore;
}
NestedMeta::Meta(Meta::NameValue(meta))
if meta.path.is_ident(DATA_SAME_FN_ATTR_PATH) =>
{
let path = parse_lit_into_expr_path(&meta.lit)?;
data_attr = DataAttr::SameFn(path);
}
NestedMeta::Meta(Meta::Path(path))
if path.is_ident(DATA_EQ_ATTR_PATH) =>
{
data_attr = DataAttr::Eq;
}
other => return Err(Error::new(other.span(), "Unknown attribute")),
}
}
}
other => {
return Err(Error::new(
other.span(),
"Expected attribute list (the form #[data(one, two)])",
));
}
}
}
}
Ok(Field {
ident,
ty,
attrs: data_attr,
})
}View on GitHub (pinned to 0f8b1195e4)