yewstack/yew · error

only structs are supported

Error message

only structs are supported

What it means

Thrown by Yew's `#[derive(Properties)]` when it is applied to a struct whose fields are positional (a tuple struct). The derive generates a builder with one setter per named prop, so `syn::Fields::Unnamed` gives it no field names to work with and the `_` arm at derive_props/mod.rs:135 calls `unimplemented!`. Because it is a panic rather than a `syn::Error`, rustc reports 'proc macro panicked' with this message.

Source

Thrown at packages/yew-macro/src/derive_props/mod.rs:135

impl Parse for DerivePropsInput {
    fn parse(input: ParseStream) -> Result<Self> {
        let input: DeriveInput = input.parse()?;
        let prop_fields = match input.data {
            syn::Data::Struct(data) => match data.fields {
                syn::Fields::Named(fields) => {
                    let mut prop_fields: Vec<PropField> = fields
                        .named
                        .into_iter()
                        .map(|f| f.try_into())
                        .collect::<Result<Vec<PropField>>>()?;

                    // Alphabetize
                    prop_fields.sort();

                    prop_fields
                }
                syn::Fields::Unit => Vec::new(),
                _ => unimplemented!("only structs are supported"),
            },
            _ => unimplemented!("only structs are supported"),
        };

        let preserved_attrs = input
            .attrs
            .iter()
            .filter(|a| should_preserve_attr(a))
            .cloned()
            .collect();

        Ok(Self {
            vis: input.vis,
            props_name: input.ident,
            generics: input.generics,
            prop_fields,
            preserved_attrs,
        })

View on GitHub (pinned to 0e4a05472f)

Solutions

  1. Convert the struct to named fields — the only field shape the derive supports: `struct Wrapper { token: String }`
  2. If the newtype must stay positional for your API, keep it private and add a separate named-field props struct for the component, constructed from the newtype
  3. As a last resort, implement `Properties` manually and provide the required `type Builder` plus its `Builder` impl yourself

Example fix

// before
#[derive(Clone, PartialEq, Properties)]
struct Wrapper(String);

// after
#[derive(Clone, PartialEq, Properties)]
struct Wrapper {
    token: String,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Writing `#[derive(Clone, PartialEq, Properties)] struct Wrapper(String);` — any `Properties` derive on a tuple struct reaches this arm. Named-field structs and unit structs (`struct Foo;`) are accepted; only positional fields hit the panic.

Common situations: Wrapping a primitive or external type as component props (`struct ApiToken(String)`), translating prop examples from frameworks where positional payloads are common, or annotating generated tuple-struct code with the derive list.

Related errors


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