dbt-labs/dbt-core · error · syn::Error

ProtoNew can only be derived for structs

Error message

ProtoNew can only be derived for structs

What it means

The ProtoNew derive macro can only be applied to struct items (Data::Struct). Applying it to an enum or union makes impl_proto_new return a syn::Error on the input's span with the message 'ProtoNew can only be derived for structs', failing compilation. This guard exists because the generated constructor logic is struct-specific.

Source

Thrown at crates/proto-rust-macros/src/lib.rs:53

        Err(err) => err.to_compile_error().into(),
    }
}

fn impl_proto_new(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
    let struct_ident = &input.ident;

    let fields = match &input.data {
        Data::Struct(s) => match &s.fields {
            Fields::Named(named) => &named.named,
            _ => {
                return Err(syn::Error::new(
                    s.fields.span(),
                    "ProtoNew only supports structs with named fields",
                ));
            }
        },
        _ => {
            return Err(syn::Error::new(
                input.span(),
                "ProtoNew can only be derived for structs",
            ));
        }
    };

    // Build parameter list and field initializers
    let mut params = Vec::new();
    let mut inits = Vec::new();
    let mut arg_docs: Vec<String> = Vec::new();

    for field in fields {
        let field_ident = field
            .ident
            .clone()
            .ok_or_else(|| syn::Error::new(field.span(), "Unnamed field not supported"))?;

        let is_enum = find_prost_enumeration_attr(&field.attrs)?;

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Remove the ProtoNew derive from the enum/union
  2. Restructure the type as a struct if a proto-style constructor is needed
  3. Implement a separate derive macro if enums need equivalent functionality

Example fix

// before
#[derive(ProtoNew)]
enum NodeKind { Leaf, Branch }
// after (derive removed; construct via normal enum variants)
enum NodeKind { Leaf, Branch }
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time: ensure the item is a struct before deriving
// enum Foo { A }  + #[derive(ProtoNew)] -> compile error pointing at the enum

Prevention

When it happens

Trigger: Adding `#[derive(ProtoNew)]` to an `enum` or `union` definition instead of a `struct`.

Common situations: Bulk-adding the derive to a module containing enums; applying derive helper patterns intended for structs to enum types; IDE auto-import applying the wrong derive attribute.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/e403a8651013e619. Report an issue: GitHub.