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
- Remove the ProtoNew derive from the enum/union
- Restructure the type as a struct if a proto-style constructor is needed
- 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
- Never place #[derive(ProtoNew)] on enums or unions
- Audit bulk-added derive attributes after refactors
- Keep enum serialization logic in a dedicated macro/impl instead of reusing ProtoNew
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
- ProtoNew only supports structs with named fields
- Unnamed field not supported
- Unsupported enum field type shape; expected i32, Option<i32>
- ProtoEnumSerde can only be derived for enums
- `name` set multiple times.
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/e403a8651013e619.
Report an issue: GitHub.