leptos-rs/leptos · error

unexpected extra argument

Error message

unexpected extra argument

What it means

Positional string-literal arguments are limited to four slots (prefix at 2, encoding at 3, endpoint at 4 after the struct name). Any further string literal in the #[server] attribute exceeds the known positional signature and is rejected as an extra argument.

Source

Thrown at server_fn_macro/src/lib.rs:1217

                    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()?),
                    4 => fn_path = Some(stream.parse()?),
                    _ => {
                        return Err(syn::Error::new(
                            stream.span(),
                            "unexpected extra argument",
                        ))
                    }
                }

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Remove the surplus string literal(s) beyond the four allowed positional slots.
  2. Convert needed options to keyword form so intent is explicit (encoding = "Url", etc.).
  3. Check the current macro docs for the accepted argument list after upgrading the crate.

Example fix

// before
#[server(MyFn, "api", "Url", "my_endpoint", "extra")]
// after
#[server(MyFn, "api", "Url", "my_endpoint")]
Defensive patterns

Strategy: validation

Validate before calling

// Positional strings allowed: prefix, encoding, endpoint (max 3 after name).
fn too_many_positional(attr: &str) -> bool {
    let strs = attr.matches ('"').count() / 2;
    strs > 3
}
assert!(!too_many_positional("#[server(MyFn, \"a\", \"b\", \"c\", \"d\")]"));

Prevention

When it happens

Trigger: #[server(MyFn, "api", "Url", "endpoint", "extra")] — five string literals; passing a note or comment-like string inside the attribute; leftover arguments after copying a template attribute.

Common situations: Users who assumed arbitrary trailing strings were accepted, or who kept an argument that a recent version of the macro no longer consumes after a signature change.

Related errors


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