yewstack/yew · error · syn::Error

this hook takes 2 arguments but 1 argument was supplied

Error message

this hook takes 2 arguments but 1 argument was supplied

What it means

Compile-time error from the use_prepared_state_with_closure! proc-macro (packages/yew-macro/src/use_prepared_state.rs:19). The macro parses exactly two comma-separated arguments: a dependency expression and a closure that must declare an explicit return type (the closure is stripped from the client-side bundle, so the type is needed on both sides). If the comma after the first argument cannot be parsed, the expression parser has usually already swallowed the only supplied argument as 'deps', so the macro reports that 2 arguments were expected but 1 was supplied.

Source

Thrown at packages/yew-macro/src/use_prepared_state.rs:19

use proc_macro2::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::{Expr, ExprClosure, ReturnType, Token, Type};

#[derive(Debug)]
pub struct PreparedState {
    closure: ExprClosure,
    return_type: Type,
    deps: Expr,
}

impl Parse for PreparedState {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        // Reads the deps.
        let deps = input.parse()?;

        input.parse::<Token![,]>().map_err(|e| {
            syn::Error::new(
                e.span(),
                "this hook takes 2 arguments but 1 argument was supplied",
            )
        })?;

        // Reads a closure.
        let expr: Expr = input.parse()?;

        let closure = match expr {
            Expr::Closure(m) => m,
            other => return Err(syn::Error::new_spanned(other, "expected closure")),
        };

        let return_type = match &closure.output {
            ReturnType::Default => {
                return Err(syn::Error::new_spanned(
                    &closure,
                    "You must specify a return type for this closure. This is used when the \

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Supply both arguments separated by a comma: use_prepared_state_with_closure!(deps, move |input: Rc<Dep>| async move { ... } -> Output)
  2. Verify you did not wrap deps and closure in a single expression (tuple or extra parens) that makes syn parse one argument
  3. Check the second argument is a real closure literal with an explicit -> ReturnType; a missing return type triggers the next error after the comma parses

Example fix

// before
use_prepared_state_with_closure!(move |id: Rc<Uuid>| async move { fetch_user(id).await } -> User)

// after
use_prepared_state_with_closure!(id, move |id: Rc<Uuid>| async move { fetch_user(id).await } -> User)
Defensive patterns

Strategy: validation

Validate before calling

// the macro requires exactly: deps , closure -> Type
// mental checklist before compiling:
// 1) deps expression present   2) comma   3) closure with `-> ReturnType`
// use_prepared_state_with_closure!(id, move |id: Rc<Uuid>| async move { fetch(id).await } -> User);

Prevention

When it happens

Trigger: Invoking use_prepared_state_with_closure!(|input| async move { ... } -> T) with only a closure and no deps argument; or writing both arguments without the separating comma; or wrapping the pair in extra parentheses so syn sees one expression.

Common situations: Writing the SSR prepared-state hook for the first time while copying the signature of the plain use_prepared_state function; migrating hand-written server preparation code to the macro form; refactoring the deps expression and accidentally deleting the comma.

Related errors


AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22). Data as JSON: /api/errors/c997e578630ea0d0. Report an issue: GitHub.