leptos-rs/leptos · error

keyword argument repeated: `custom`

Error message

keyword argument repeated: `custom`

What it means

The #[server] macro parser errors when the `custom` keyword argument appears more than once. `custom` supplies a custom wrapper type for the server function; since the wrapper stored in custom_wrapper can only hold one value, duplicates are rejected at compile time.

Source

Thrown at server_fn_macro/src/lib.rs:1157

                            ));
                        } else if output.is_some() {
                            return Err(syn::Error::new(
                                key.span(),
                                "keyword argument repeated: `output`",
                            ));
                        }
                        output = Some(stream.parse()?);
                    } else if key == "server" {
                        if server.is_some() {
                            return Err(syn::Error::new(
                                key.span(),
                                "keyword argument repeated: `server`",
                            ));
                        }
                        server = Some(stream.parse()?);
                    } else if key == "client" {
                        if client.is_some() {
                            return Err(syn::Error::new(
                                key.span(),
                                "keyword argument repeated: `client`",
                            ));
                        }
                        client = Some(stream.parse()?);
                    } else if key == "custom" {
                        if custom_wrapper.is_some() {
                            return Err(syn::Error::new(
                                key.span(),
                                "keyword argument repeated: `custom`",
                            ));
                        }
                        custom_wrapper = Some(stream.parse()?);
                    } else if key == "impl_from" {
                        if impl_from.is_some() {
                            return Err(syn::Error::new(
                                key.span(),
                                "keyword argument repeated: `impl_from`",

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Keep a single `custom = ...` entry and delete the duplicate.
  2. If multiple wrapper behaviors are needed, combine them into one wrapper type instead of two `custom` args.
  3. Update wrapper macros to emit `custom` only when not already present.

Example fix

// before
#[server(custom = WrapperA, custom = WrapperB)]
async fn save(data: String) -> Result<(), ServerFnError> { todo!() }

// after
#[server(custom = WrapperA)]
async fn save(data: String) -> Result<(), ServerFnError> { todo!() }
Defensive patterns

Strategy: validation

Validate before calling

// Pre-commit check for duplicate `custom` args:
// grep -rnE '#\[server\([^)\n]*custom\s*=[^)\n]*custom\s*=' src/ && exit 1 || exit 0

Prevention

When it happens

Trigger: Writing #[server(custom = A, custom = B)] in one attribute, or a macro_rules! layer appending `custom` when the user already set it.

Common situations: Copy-pasted attribute args, composing wrapper macros that each add a custom wrapper, refactoring the wrapper type without removing the old entry.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/372d26e99760b99b. Report an issue: GitHub.