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

Multiple fields named

Error message

Multiple fields named: `{}`

What it means

This compile-time error fires when two or more fields in a `#[derive(MultipartForm)]` struct resolve to the same serialization name (after considering `#[multipart(rename = "...")]`). The macro inserts each serialization name into a `HashSet` at line 122-130 and rejects duplicates because it cannot disambiguate which Rust field should receive a given multipart part.

Solutions

  1. Rename one of the conflicting fields so each has a unique serialization name
  2. Remove the `#[multipart(rename = ...)]` that causes the collision
  3. Merge the two fields into a single field if they truly represent the same multipart part

Example fix

// before
#[derive(MultipartForm)]
struct Form {
    avatar: Bytes,
    #[multipart(rename = "avatar")]
    photo: Bytes,
}

// after
#[derive(MultipartForm)]
struct Form {
    avatar: Bytes,
    banner: Bytes,
}
Defensive patterns

Strategy: validation

Validate before calling

// Before compiling, check that all field names (including renames) are unique.
// Each field's serialization name = #[multipart(rename = "...")] value or the Rust field name.
// Ensure no two fields produce the same serialization name.

Prevention

When it happens

Trigger: Two fields with the same name, or two fields where one is renamed to match another's name (or default name). For example, `struct Form { a: Bytes, #[multipart(rename = "a")] b: Bytes }` will collide because both serialize as `"a"`.

Common situations: Using `rename` to map multiple fields to the same multipart field name by mistake, or copy-pasting field names during refactoring.

Related errors


AI-assisted analysis of actix/actix-web@4d435abc28 (2026-08-09). Data as JSON: /api/errors/cb5a95496b767b90. Report an issue: GitHub.

Appendix: source

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

            Ok(ParsedField {
                serialization_name,
                rust_name,
                limit,
                ty: &field.ty,
            })
        })
        .collect::<Result<Vec<_>, TokenStream>>()
    {
        Ok(attrs) => attrs,
        Err(err) => return err,
    };

    // Check that field names are unique
    let mut set = HashSet::new();
    for field in &parsed {
        if !set.insert(field.serialization_name.clone()) {
            return compile_err(syn::Error::new(
                field.rust_name.span(),
                format!("Multiple fields named: `{}`", field.serialization_name),
            ));
        }
    }

    // Return value when a field name is not supported by the form
    let unknown_field_result = if attrs.deny_unknown_fields {
        quote!(::std::result::Result::Err(
            ::actix_multipart::MultipartError::UnknownField(field.name().unwrap().to_string())
        ))
    } else {
        quote!(::actix_multipart::form::discard_field(field, limits).await)
    };

    // Value for duplicate action
    let duplicate_field = match attrs.duplicate_field {
        DuplicateField::Ignore => quote!(::actix_multipart::form::DuplicateField::Ignore),

View on GitHub (pinned to 4d435abc28)