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
- Keep a single `custom = ...` entry and delete the duplicate.
- If multiple wrapper behaviors are needed, combine them into one wrapper type instead of two `custom` args.
- 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
- One `custom = ...` wrapper per attribute.
- Compose behaviors into a single wrapper type instead of stacking `custom` args.
- Make wrapper macros conditional when the user already sets `custom`.
- Run cargo check before committing macro-based code.
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
- keyword argument repeated: `encoding`
- keyword argument repeated: `endpoint`
- `encoding` and `input` should not both be specified
- keyword argument repeated: `input`
- `encoding` and `output` should not both be specified
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/372d26e99760b99b.
Report an issue: GitHub.