linebender/druid · error

Expected attribute list (the form #[data(one, two)])

Error message

Expected attribute list (the form #[data(one, two)])

What it means

druid-derive expects the helper attribute to be used as a meta list of the form #[data(one, two)] (a parenthesized list of nested attributes). If the attribute appears in some other form — a bare path like #[data], a name-value form like #[data = "x"], or a non-list meta — the parser rejects it with this message.

Solutions

  1. Wrap the arguments in parentheses: #[data(eq)] or #[data(ignore)].
  2. Remove the attribute entirely if no options are needed (an empty #[data] is not valid).
  3. Check the derive macro docs for the exact list syntax required by your druid version.

Example fix

// before
#[data]
field: i32,
// after
#[data(eq)]
field: i32,
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the helper attribute is always a list before compiling:
fn is_list_form(attr: &str) -> bool {
    let start = attr.find('(');
    let end = attr.rfind(')');
    matches!((start, end), (Some(s), Some(e)) if e > s)
}
// assert!(is_list_form("#[data(eq)]"));

Prevention

When it happens

Trigger: Using #[data] without parentheses on a field/variant, using #[data = "value"] name-value syntax, or any Meta form other than a list when the parser calls parse_ast.

Common situations: Forgetting the parentheses after the helper attribute name, confusing the helper attribute with the derive name itself, migrating code from crates with different attribute syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/2460ac1f6049bc02. Report an issue: GitHub.

Appendix: source

Thrown at druid-derive/src/attr.rs:165

                                    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,
        })
    }

    /// The tokens to be used as the function for 'same'.
    pub fn same_fn_path_tokens(&self) -> TokenStream {
        match &self.attrs {
            DataAttr::SameFn(f) => quote!(#f),

View on GitHub (pinned to 0f8b1195e4)