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

  1. Convert every remaining positional argument to keyword form: prefix = "...", encoding = "...", endpoint = "...".
  2. Alternatively, drop all keyword arguments and use the legacy positional order with string literals.
  3. 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

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


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