actix/actix-web · critical · syn::Error
`MultipartForm` can only be derived for structs
Error message
`MultipartForm` can only be derived for structs
What it means
A compile-time syn::Error emitted by the MultipartForm derive macro (multipart-derive/src/lib.rs:66) when #[derive(MultipartForm)] is applied to anything other than a struct - i.e. an enum or union. The macro matches input.data against syn::Data::Struct (lib.rs:63) and, on mismatch, returns this error via compile_err. There is a separate, similar message for structs without named fields (lib.rs:76).
Solutions
- Define a struct with named fields and derive MultipartForm on it.
- If you need variants, wrap the struct in an enum manually and extract MultipartForm on the inner struct.
- Ensure all fields are named (not tuple/struct-unit); the macro requires syn::Fields::Named (lib.rs:74).
Example fix
// before
#[derive(MultipartForm)]
enum Shape { A(Text<String>), B(TempFile) } // compile error
// after
#[derive(MultipartForm)]
struct Form { label: Text<String>, file: Option<TempFile> } Defensive patterns
Strategy: type-guard
Validate before calling
// The macro only accepts structs with named fields; check before annotating
Type guard
// Only derive on structs (named fields); never on enums/unions
#[derive(MultipartForm)]
struct Upload {
name: Text<String>,
file: TempFile,
}
// enum E { ... } // do NOT put #[derive(MultipartForm)] here Prevention
- Derive MultipartForm only on structs with named fields.
- For polymorphism, keep the form a struct and branch in handler logic.
- Read the macro docs: tuple/unit structs and enums are unsupported.
When it happens
Trigger: Annotating an enum or union with #[derive(MultipartForm)]: e.g. `#[derive(MultipartForm)] enum E { ... }`. The build fails with this message pointing at the type's span.
Common situations: Trying to model a discriminated form payload as an enum; copy-pasting the derive onto the wrong item; misunderstanding that the macro only supports plain structs with named fields.
Related errors
- Could not parse size limit
- Duplicate field found
- `MultipartForm` can only be derived for a struct with named…
- Multiple fields named
- Required field is missing
AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09).
Data as JSON: /api/errors/3690a299ad529506.
Report an issue: GitHub.
Appendix: source
Thrown at actix-multipart-derive/src/lib.rs:66
ty: &'t Type,
}
/// Implements `MultipartCollect` for a struct so that it can be used with the `MultipartForm`
/// extractor.
///
/// See [`actix_multipart::form::MultipartForm`] for supported fields and attributes.
///
/// [`actix_multipart::form::MultipartForm`]: https://docs.rs/actix-multipart/latest/actix_multipart/form/struct.MultipartForm.html
#[proc_macro_derive(MultipartForm, attributes(multipart))]
pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input: syn::DeriveInput = parse_macro_input!(input);
let name = &input.ident;
let data_struct = match &input.data {
syn::Data::Struct(data_struct) => data_struct,
_ => {
return compile_err(syn::Error::new(
input.ident.span(),
"`MultipartForm` can only be derived for structs",
))
}
};
let fields = match &data_struct.fields {
syn::Fields::Named(fields_named) => fields_named,
_ => {
return compile_err(syn::Error::new(
input.ident.span(),
"`MultipartForm` can only be derived for a struct with named fields",
))
}
};
let attrs = match MultipartFormAttrs::from_derive_input(&input) {
Ok(attrs) => attrs,View on GitHub (pinned to 4d435abc28)