biomejs/biome · error · syn::Error

Only one attribute expected inside deprecated()

Error message

Only one attribute expected inside deprecated()

What it means

Compile-time error from the #[deserializable] derive (struct_field_attrs.rs:103). The deprecated(...) attribute accepts at most one inner option; the parser stores the first message/use_instead it sees, and a second item inside the same list makes the deprecated.is_some() branch return this 'Only one attribute expected inside deprecated()' error.

Source

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

                            }
                        }
                        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!(
                                            "Unexpected attribute inside deprecated(): {path_text}"
                                        ),
                                    ));
                                };
                                Ok(())
                            })?;

View on GitHub (pinned to 405dedb0ff)

Solutions

  1. Keep exactly one option inside deprecated(); prefer use_instead = "NewField" when a replacement field exists - Biome derives the user-facing message from it
  2. If both a custom message and a replacement are genuinely needed, check the current macro source/changeset - as of this code only one is allowed, so pick the more useful one

Example fix

// before
#[deserializable(deprecated(message = "Use new_field", use_instead = "NewField"))]
pub old_field: bool,

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

Strategy: validation

Validate before calling

// Rust - exactly one item inside deprecated()
#[deserializable(deprecated(use_instead = "NewField"))] // not both keys at once
pub old_field: bool,

Prevention

When it happens

Trigger: Writing both keys in one attribute: #[deserializable(deprecated(message = "...", use_instead = "..."))], or repeating a key: deprecated(message = "a", message = "b").

Common situations: Wanting to show both a custom message and a replacement-field suggestion in the same deprecation; merging two reviewed attribute snippets produces a list with two items.

Related errors


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