leptos-rs/leptos · error
If you use keyword arguments (e.g., `name` = Something), the
Error message
If you use keyword arguments (e.g., `name` = Something), then you can no longer use arguments without a keyword.
What it means
The #[server] macro does not allow mixing styles: once a `key = value` keyword argument is seen (use_key_and_value is set), any subsequent argument without a keyword — here a string literal — is rejected with this message. All remaining arguments must use `key = value` form.
Source
Thrown at server_fn_macro/src/lib.rs:1209
"keyword argument repeated: `protocol`",
));
}
protocol = Some(stream.parse()?);
} else {
return Err(lookahead.error());
}
} else {
let value = key_or_value;
if use_key_and_value {
return Err(syn::Error::new(
value.span(),
"positional argument follows keyword argument",
));
}
if arg_pos == 1 {
struct_name = Some(value)
} else {
return Err(syn::Error::new(
value.span(),
"expected string literal",
));
}
}
} else if lookahead.peek(LitStr) {
if use_key_and_value {
return Err(syn::Error::new(
stream.span(),
"If you use keyword arguments (e.g., `name` = \
Something), then you can no longer use arguments \
without a keyword.",
));
}
match arg_pos {
1 => return Err(lookahead.error()),
2 => prefix = Some(stream.parse()?),
3 => encoding = Some(stream.parse()?),View on GitHub (pinned to 32d20f6c9d)
Solutions
- Convert every remaining positional argument to keyword form: prefix = "...", encoding = "...", endpoint = "...".
- Alternatively, drop all keyword arguments and use the legacy positional order with string literals.
- Audit the attribute so no bare strings follow any `key = value` pair.
Example fix
// before #[server(name = "MyFn", "api", "Url")] // after #[server(name = "MyFn", prefix = "api", encoding = "Url")]
Defensive patterns
Strategy: validation
Validate before calling
// Never mix: if any 'key =' appears, every argument must have 'key ='.
fn style_is_consistent(attr: &str) -> bool {
let args: Vec<&str> = attr.trim_matches(|c| c == '[' || c == ']').split(',').map(str::trim).collect();
let kw = args.iter().any(|a| a.contains('='));
!kw || args.iter().all(|a| a.contains('='))
} Prevention
- Convert legacy positional attributes fully to keyword form in one edit
- Never append bare strings to keyword-style attributes
- Document the project-wide convention: keyword-only arguments
When it happens
Trigger: #[server(name = "MyFn", "api/prefix")] — a bare string after a keyword argument; partially converting a legacy positional call to keyword form; appending a new option without its key.
Common situations: Developers upgrading from the legacy positional syntax (name, prefix, encoding, endpoint) who convert only the first argument to `name = ...` and leave the rest positional.
Related errors
- keyword argument repeated: `impl_deref`
- keyword argument repeated: `protocol`
- positional argument follows keyword argument
- expected string literal
- unexpected extra argument
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/425ad05ca11dcd4a.
Report an issue: GitHub.