actix/actix-web · error · syn::Error

`MultipartForm` can only be derived for a struct with named

Error message

`MultipartForm` can only be derived for a struct with named fields

What it means

Even among structs, the derive requires named fields. At actix-multipart-derive/src/lib.rs:76 only `syn::Fields::Named` is accepted; tuple structs (`struct Foo(String)`) and unit structs (`struct Foo;`) are rejected because the generated `from_state` impl references each field by name (e.g. `rust_name: <Ty>::from_state(...)`), which is impossible without names.

Source

Thrown at actix-multipart-derive/src/lib.rs:76

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,
        Err(err) => return err.write_errors().into(),
    };

    // Parse the field attributes
    let parsed = match fields
        .named
        .iter()
        .map(|field| {
            let rust_name = field.ident.as_ref().unwrap();
            let attrs = FieldAttrs::from_field(field).map_err(|err| err.write_errors())?;

View on GitHub (pinned to 937960ca67)

Solutions

  1. Convert tuple/unit fields to named fields: `struct Upload { file: File }`.
  2. If the struct is intentionally empty, remove the derive (an empty multipart form is usually a mistake).

Example fix

// before
#[derive(MultipartForm)]
struct Upload(File);

// after
#[derive(MultipartForm)]
struct Upload {
    file: Field,
}
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time: ensure fields are named. Check the declaration uses
// `struct Name { field: Type, ... }`, not `struct Name(Type)` or `struct Name;`.

Prevention

When it happens

Trigger: Deriving `MultipartForm` on a tuple struct like `struct Upload(File);` or a unit struct `struct Empty;`.

Common situations: Newtype wrappers around a single field, or empty marker structs that accidentally inherit the attribute during a refactor.

Related errors


AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06). Data as JSON: /data/errors/73b0dcfae6a23a9c.json. Report an issue: GitHub.