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

`serde_multikey` was applied to a non Serialize/Deserialize

Error message

`serde_multikey` was applied to a non Serialize/Deserialize struct

What it means

generate_main_struct inspects the struct's remaining attributes to determine whether it derives serde Serialize and/or Deserialize (get_ser_de). serde_multikey's generated code relies on serde try_from/into plumbing, so if the struct has neither Serialize nor Deserialize configured, the macro rejects it with this compile error.

Source

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

    let main_struct = generate_main_struct(input.clone())?;

    let proxy_struct = generate_proxy_struct(input)?;

    Ok(quote!(
    #main_struct
    #proxy_struct
    )
    .into())
}

/// Generate the main struct. It's a copy of the original struct, but with most
/// ser/de attributes removed, and serde try_from/into `__MultiKey{}` added.
fn generate_main_struct(mut input: ItemStruct) -> Result<TokenStream2, Error> {
    let (serialize, deserialize) = get_ser_de(&input.attrs)?;
    let has_utoipa_schema = get_and_remove_utoipa_schema(&mut input.attrs)?;

    if !deserialize && !serialize {
        return Err(Error::new(
            Span::call_site(),
            "`serde_multikey` was applied to a non Serialize/Deserialize struct",
        ));
    }

    // remove serde and utoipa attributes from fields
    for field in input.fields.iter_mut() {
        let attrs = mem::take(&mut field.attrs);
        field.attrs = attrs
            .into_iter()
            .filter(|attr| {
                !(attr.path().is_ident("serde_multikey")
                    || attr.path().is_ident("serde")
                    || attr.path().is_ident("serde_as")
                    || attr.path().is_ident("schema"))
            })
            .collect();
    }

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Add #[derive(Serialize, Deserialize)] (or at least the one you need) to the struct alongside #[serde_multikey].
  2. Ensure `serde` is a dependency with the `derive` feature and that the derives are imported.

Example fix

// before
#[serde_multikey(fields(id))]
struct MultiKey { id: String, name: String }
// after
#[derive(Serialize, Deserialize)]
#[serde_multikey(fields(id))]
struct MultiKey { id: String, name: String }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the struct carries serde derives before applying serde_multikey:
#[derive(Serialize, Deserialize)]
#[serde_multikey(fields(key))]
struct MyKey { key: String }

Prevention

When it happens

Trigger: Annotating a plain struct with #[serde_multikey(...)] when the struct lacks both #[derive(Serialize)] / #[derive(Deserialize)] (or equivalent serde derive attributes).

Common situations: Adding serde_multikey to an internal struct that was never serde-annotated; forgetting the serde derive import (`use serde::{Serialize, Deserialize};`) so the derive attribute is absent.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/f56b5392e2b4c041. Report an issue: GitHub.