leptos-rs/leptos · error

Unrecognized attribute, expected #[server(...)]

Error message

Unrecognized attribute, expected #[server(...)]

What it means

When collecting the other attributes on the server function item, the macro passes through known/allowed attributes (e.g. #[doc], #[deny(...)], #[ignore] and similar supported ones) and rejects anything else with 'Unrecognized attribute, expected #[server(...)]'.

Source

Thrown at server_fn_macro/src/lib.rs:1425

                            "Unrecognized #[server] attribute, expected \
                             #[server(default)] or #[server(rename = \
                             \"fieldName\")]",
                        )),
                    }
                } else if attr.path().is_ident("doc") {
                    // Allow #[doc = "documentation"]
                    Ok(attr.clone())
                } else if attr.path().is_ident("allow") {
                    // Allow #[allow(...)]
                    Ok(attr.clone())
                } else if attr.path().is_ident("deny") {
                    // Allow #[deny(...)]
                    Ok(attr.clone())
                } else if attr.path().is_ident("ignore") {
                    // Allow #[ignore]
                    Ok(attr.clone())
                } else {
                    Err(Error::new(
                        attr.span(),
                        "Unrecognized attribute, expected #[server(...)]",
                    ))
                }
            })
            .collect::<Result<Vec<_>>>()?;
        arg.attrs = vec![];
        Ok(ServerFnArg {
            arg,
            server_fn_attributes,
        })
    }
}

/// The body of a server function.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ServerFnBody {

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Remove the unrecognized attribute from the function.
  2. If it must apply, reorder so the other macro expands before #[server] or apply it to the generated struct via the macro's supported passthrough.
  3. Check the crate version's supported attribute list (doc, cfg, deny/allow, ignore, etc.) and use only those.

Example fix

// before
#[server]
#[inline]
async fn my_fn() -> Result<(), ServerFnError> { Ok(()) }
// after
#[server]
async fn my_fn() -> Result<(), ServerFnError> { Ok(()) }
Defensive patterns

Strategy: validation

Validate before calling

// Whitelist of attributes accepted alongside #[server] (doc, cfg, allow/deny, ignore, ...).
const ALLOWED: &[&str] = &["doc", "cfg", "allow", "deny", "ignore"];
let attr = "inline";
assert!(ALLOWED.contains(&attr), "attribute #[{attr}] is not accepted next to #[server]");

Prevention

When it happens

Trigger: Placing an attribute the macro doesn't whitelist on the #[server] function, e.g. #[inline], #[deprecated] (depending on version), or a custom proc-macro attribute from another crate that must run before #[server].

Common situations: Stacking helper macros from other crates on server functions; cargo-upgrading server_fn and losing support for an attribute previously accepted.

Related errors


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