quickwit-oss/quickwit · error · proc-macro compile error

`serde_multikey` require list-style arguments

Error message

`serde_multikey` require list-style arguments

What it means

The `#[serde_multikey]` attribute must be written in list form — `#[serde_multikey(...)]`. If the macro sees it used as a path (`#[serde_multikey]`) or name-value form (`#[serde_multikey = "x"]`), `parse_attributes` rejects it because MultiKeyOptions can only be parsed from the parenthesized token list.

Solutions

  1. Rewrite the attribute in list form, e.g. `#[serde_multikey(main_key = "...", sub_key = "...")]`.
  2. Check the MultiKeyOptions struct in quickwit-macros for the accepted argument names and pass them inside the parentheses.
  3. If the attribute was intended as a no-op marker, delete it entirely.

Example fix

// before
#[serde_multikey]
my_field: MyType,
// after
#[serde_multikey(main_key = "timestamp", sub_key = "source")]
my_field: MyType,
Defensive patterns

Strategy: validation

Validate before calling

// attribute must be list-style: check before compiling
// #[serde_multikey(...)]  OK
// #[serde_multikey] or #[serde_multikey = "x"]  ERROR

Prevention

When it happens

Trigger: Compiling a field annotated with bare `#[serde_multikey]` or `#[serde_multikey = "something"]` instead of `#[serde_multikey(options...)]`.

Common situations: Following outdated documentation that showed the attribute without arguments; writing `#[serde_multikey = "true"]` by analogy with boolean serde attributes; a typo stripping the parentheses.

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 quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/5e3b6b51a569c6ad. Report an issue: GitHub.

Appendix: source

Thrown at quickwit/quickwit-macros/src/lib.rs:470

fn parse_attributes(
    attributes: Vec<Attribute>,
    field_name: &Ident,
) -> Result<(Option<MultiKeyOptions>, Vec<Attribute>), Error> {
    let (mut multikey_attributes, normal_attributes): (Vec<_>, _) = attributes
        .into_iter()
        .partition(|attr| attr.path().is_ident("serde_multikey"));

    if multikey_attributes.len() > 1 {
        let last = multikey_attributes.last().unwrap();
        return Err(Error::new(
            last.pound_token.spans[0],
            "`serde_multikey` was applied multiple time to the same field",
        ));
    }
    let options = if let Some(multikey_attribute) = multikey_attributes.pop() {
        let Meta::List(meta_list) = multikey_attribute.meta else {
            return Err(Error::new(
                multikey_attribute.pound_token.spans[0],
                "`serde_multikey` require list-style arguments",
            ));
        };
        let mut options: MultiKeyOptions = syn::parse2(meta_list.tokens)?;
        options.main_field_name = field_name.clone();
        Some(options)
    } else {
        None
    };

    Ok((options, normal_attributes))
}

View on GitHub (pinned to a39730c5cd)