biomejs/biome · error · syn::Error

Unexpected attribute: {meta_text}

Error message

Unexpected attribute: {meta_text}

What it means

Compile-time error from the #[deserializable] derive of biome_deserialize_macros (struct_field_attrs.rs:97). Inside the deprecated(...) attribute on a struct field, every nested item must be a name-value pair with a string literal (message = "..." or use_instead = "..."). Any other shape - a bare word like deprecated(note), a nested list, or a non-string literal like deprecated(message = 5) - fails the Meta::NameValue-with-Lit::Str pattern match and produces this 'Unexpected attribute' error at the offending token span.

Source

Thrown at crates/biome_deserialize_macros/src/deserializable_derive/struct_field_attrs.rs:97

                            ..
                        }) => {
                            if path.is_ident("rename") {
                                opts.rename = Some(s.value())
                            } else if path.is_ident("validate") {
                                opts.validate = Some(s.parse()?)
                            }
                        }
                        Meta::List(_) if meta.path().is_ident("deprecated") => {
                            let mut deprecated = None;
                            parse_meta_list(meta, |meta| {
                                let Meta::NameValue(MetaNameValue {
                                    path,
                                    lit: Lit::Str(s),
                                    ..
                                }) = meta
                                else {
                                    let meta_text = meta.to_token_stream().to_string();
                                    return Err(Error::new(
                                        meta.span(),
                                        format_args!("Unexpected attribute: {meta_text}"),
                                    ));
                                };
                                deprecated = if deprecated.is_some() {
                                    return Err(Error::new(
                                        meta.span(),
                                        "Only one attribute expected inside deprecated()",
                                    ));
                                } else if path.is_ident("message") {
                                    Some(DeprecatedField::Message(s.value()))
                                } else if path.is_ident("use_instead") {
                                    Some(DeprecatedField::UseInstead(s.value()))
                                } else {
                                    let path_text = path.to_token_stream().to_string();
                                    return Err(Error::new(
                                        path.span(),
                                        format_args!(

View on GitHub (pinned to 405dedb0ff)

Solutions

  1. Use the two supported keys with string literals: #[deserializable(deprecated(message = "Use `otherField` instead."))] or deprecated(use_instead = "OtherField")
  2. If you wanted version metadata like since = "1.2", drop it - only message and use_instead are supported inside deprecated()
  3. Run cargo check on the crate after editing attributes; the error points at the exact nested token span

Example fix

// before
#[deserializable(deprecated(since = "1.2"))]
pub old_option: bool,

// after
#[deserializable(deprecated(use_instead = "NewOption"))]
pub old_option: bool,
Defensive patterns

Strategy: validation

Validate before calling

// Rust - only these two shapes are valid inside deprecated()
#[deserializable(deprecated(message = "Use `new_field` instead."))]
pub old_field: bool,
#[deserializable(deprecated(use_instead = "NewField"))]
pub other: bool,

Prevention

When it happens

Trigger: Writing #[deserializable(deprecated(anything))] (bare path), #[deserializable(deprecated(message = 5))] (integer literal), or #[deserializable(deprecated("use bar"))] (string literal instead of name-value) on a field of a type deriving Deserializable.

Common situations: Adding deprecation metadata to configuration option structs in biome_configuration or downstream crates using biome_deserialize; copy-pasting serde-style syntax (since = "1.2", note = "...") which this macro does not support inside deprecated().

Related errors


AI-assisted analysis of biomejs/biome@405dedb0ff (2026-08-20). Data as JSON: /api/errors/757af445abd27f80. Report an issue: GitHub.