quickwit-oss/quickwit · error · proc-macro compile error
`serde_multikey` was applied multiple time to the same field
Error message
`serde_multikey` was applied multiple time to the same field
What it means
This compile-time proc-macro error comes from quickwit's custom `#[serde_multikey(...)]` attribute. The `parse_attributes` helper partitions a field's attributes and requires at most one `serde_multikey`; applying it more than once to the same field is ambiguous (which set of options should win?), so the macro emits a syn::Error pointing at the last duplicate occurrence.
Source
Thrown at quickwit/quickwit-macros/src/lib.rs:463
if res.proxy_fields.is_empty() {
todo!("throw error")
}
Ok(res)
}
}
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
};
View on GitHub (pinned to a39730c5cd)
Solutions
- Remove the duplicate `#[serde_multikey(...)]` attribute from the field, keeping only one.
- Merge the two attribute argument lists into a single `#[serde_multikey(...)]` if both sets of options are needed.
- If the duplicate came from a macro or code generator you control, deduplicate the attribute before emitting the struct.
Example fix
// before #[serde_multikey(main_key = "a", sub_key = "b")] #[serde_multikey(main_key = "a", sub_key = "c")] my_field: MyType, // after #[serde_multikey(main_key = "a", sub_key = "c")] my_field: MyType,
Defensive patterns
Strategy: validation
Validate before calling
// compile-time: ensure each field carries at most one serde_multikey attribute
let dupes = fields.iter().filter(|f| f.attrs.iter().filter(|a| a.path().is_ident("serde_multikey")).count() > 1).count();
assert_eq!(dupes, 0, "duplicate serde_multikey attribute"); Prevention
- Search fields for `serde_multikey` before adding it again (grep the struct definition).
- When merging branches, resolve attribute conflicts on derived structs explicitly.
- Keep multi-key field annotations documented so contributors know one is already present.
When it happens
Trigger: Compiling a struct derived via the proxy-struct macro (generate_proxy_struct) where a single field is annotated with two or more `#[serde_multikey(...)]` attributes.
Common situations: Merging code from two branches that each added `serde_multikey` to the same field; copy-pasting an attribute line and forgetting to remove the original; mechanically adding the attribute without noticing it was already present.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- the attribute can only be applied to struct
- `serde_multikey` was applied to a non Serialize/Deserialize
- `serde_multikey` was applied to a tuple-struct or an empty s
- structure implement serialize but no serializer defined
- structure doesn't implement serialize but a serializer is de
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/5e5a3ce1da3c2171.
Report an issue: GitHub.