risingwavelabs/risingwave · error
You can't use the macro on this type
Error message
You can't use the macro on this type
What it means
The #[serde_prefix_all] attribute macro only supports enums and structs. It fails at compile time when applied to a union or any other non-enum/non-struct item, because there is no defined way to prefix fields or variants of such a type. The error is emitted by try_prefix_all in the proc-macro crate when the derive input's Data falls into neither the Enum nor Struct arm.
Source
Thrown at src/common/proc_macro/src/serde_prefix_all.rs:134
mode: mode.unwrap_or(Mode::Rename),
})
}
pub(crate) fn try_prefix_all(
args: AttributeArgs,
mut input: DeriveInput,
) -> syn::Result<TokenStream> {
let ParsedArgs {
prefix,
prefix_span,
mode,
} = parse_args(args)?;
match &mut input.data {
Data::Enum(item_enum) => handle_enum(item_enum, &prefix[..], mode)?,
Data::Struct(item_struct) => handle_struct(item_struct, &prefix[..], mode)?,
_ => {
return Err(Error::new(
prefix_span,
"You can't use the macro on this type",
));
}
};
Ok(input.to_token_stream().into())
}
fn create_attribute(prefix: &str, field_name: &str, mode: Mode) -> Attribute {
let attr_prefix = format!("{prefix}{field_name}");
match mode {
Mode::Rename => parse_quote! { #[serde(rename = #attr_prefix)] },
Mode::Alias => parse_quote! { #[serde(alias = #attr_prefix)] },
}
}
fn take_skip_attr(attrs: &mut Vec<Attribute>) -> syn::Result<bool> {View on GitHub (pinned to 6469eb736d)
Solutions
- Remove the #[serde_prefix_all] attribute from the union; the macro cannot run on unions.
- Convert the type to a struct (or enum) if prefixing semantics are actually needed.
- Handle prefixing manually with #[serde(rename = "...")] on each field instead.
- Move the attribute to a sibling struct/enum that wraps or serializes the union's payload.
Example fix
// before
#[serde_prefix_all("cfg_")]
union Packed {
raw: u64,
f: f64,
}
// after
#[derive(Serialize)]
#[serde_prefix_all("cfg_")]
struct PackedView {
raw: u64,
} Defensive patterns
Strategy: validation
Validate before calling
// Compile-time check before relying on the macro:
macro_rules! assert_is_struct_or_enum {
($t:ty) => {
const _: () = {
// Applying serde_prefix_all to a union fails to compile;
// only attach it to structs/enums.
};
};
}
// Practical pre-check: confirm the item below the attribute is
// `struct` or `enum` — never `union`. Prevention
- Only place #[serde_prefix_all] directly above `struct` or `enum` declarations.
- Never attach the macro to `union` types used for FFI/byte reinterpretation.
- If converting a struct to a union, remove the attribute first.
- Let the compiler catch it early: run `cargo check` immediately after adding the attribute.
When it happens
Trigger: Annotating a Rust `union` (or any item whose parsed DeriveInput data is not Data::Enum or Data::Struct) with #[serde_prefix_all("prefix")]. E.g. `#[serde_prefix_all("cfg_")] union Foo { a: u32, b: f32 }`.
Common situations: Developers converting a serde type to use the prefix macro accidentally apply it to a union used for FFI or low-level byte reinterpretation; copy-pasting the attribute above the wrong item; changing a struct into a union later and leaving the attribute in place.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Expected #[serde_prefix_all(skip)]
- (serde_json deserialization error)
- SinkError::Config(anyhow!(e))
- {serde_json deserialization error for PulsarConfig from prop
- {serde_json URL parse error for RedisCommon}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/14e6eafb9eabd206.
Report an issue: GitHub.