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

Multiple fields named: `{}`

Error message

Multiple fields named: `{}`

What it means

After resolving each field's serialization name (either the Rust name or a `#[multipart(rename = "...")]` value), the macro builds a `HashSet` and rejects duplicates at actix-multipart-derive/src/lib.rs:122-129. Two fields mapping to the same incoming form name would make parsing ambiguous, so the macro aborts.

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 937960ca67)

Solutions

  1. Give each field a unique serialization name by adjusting or removing the conflicting `rename`.
  2. If two fields genuinely share one incoming part, merge them into a single field of a composite type.
  3. Set `#[multipart(duplicate_field = "deny|ignore|replace")]` only if you intend runtime duplicate handling — this does not bypass the compile-time name-uniqueness check.

Example fix

// before
#[derive(MultipartForm)]
struct Form {
    #[multipart(rename = "file"))]
    a: Field,
    #[multipart(rename = "file"))]
    b: Field,
}

// after
#[derive(MultipartForm)]
struct Form {
    #[multipart(rename = "file_a"))]
    a: Field,
    #[multipart(rename = "file_b"))]
    b: Field,
}
Defensive patterns

Strategy: validation

Validate before calling

// Collect all serialization names (rust name or #[multipart(rename)]) into a set
// and assert uniqueness before relying on the derive.
fn assert_unique_names(names: &[&str]) {
    let mut seen = std::collections::HashSet::new();
    for n in names {
        assert!(seen.insert(*n), "duplicate field name: {}", n);
    }
}
// assert_unique_names(&["file_a", "file_b", "file_a"]); // panics in your test

Prevention

When it happens

Trigger: Two fields renamed to the same string, e.g. `#[multipart(rename = "file")]` on two fields; or a `rename` that collides with another field's default name.

Common situations: Renaming fields to match a legacy/external form field name and accidentally clashing with an existing field, or copy-pasting a rename attribute between fields.

Related errors


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