dbt-labs/dbt-core · error · syn::Error
ProtoNew only supports structs with named fields
Error message
ProtoNew only supports structs with named fields
What it means
The ProtoNew derive macro (impl_proto_new, invoked via derive_proto_new) only supports structs whose fields are all named (Fields::Named). Applying #[derive(ProtoNew)] to a tuple struct or unit struct makes the macro return a syn::Error at the fields' span, producing a compile-time error. Named fields are required because the macro generates a constructor keyed by field name.
Source
Thrown at crates/proto-rust-macros/src/lib.rs:46
/// and the initializer converts the enum value(s) back to i32 as needed.
#[proc_macro_derive(ProtoNew, attributes(prost))]
pub fn derive_proto_new(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
match impl_proto_new(&input) {
Ok(ts) => ts.into(),
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();
View on GitHub (pinned to 0267ce9170)
Solutions
- Convert the struct to use named fields
- Remove the ProtoNew derive from the tuple/unit struct and construct it directly
- If ProtoNew should support tuple structs, extend the macro to handle Fields::Unnamed
Example fix
// before
#[derive(ProtoNew)]
struct Column(u32, String);
// after
#[derive(ProtoNew)]
struct Column {
index: u32,
name: String,
} Defensive patterns
Strategy: validation
Validate before calling
// Compile-time: the derive itself is the guard; prefer validating struct shape in CI // cargo check fails with this message when applied to tuple/unit structs
Prevention
- Only apply #[derive(ProtoNew)] to structs with named fields
- Read the compile error span — it points at the offending fields declaration
- If wrapping values, use a named-field struct with one field instead of a tuple struct
When it happens
Trigger: Adding `#[derive(ProtoNew)]` to a tuple struct like `struct Foo(u32);` or a unit struct like `struct Foo;`.
Common situations: Copy-pasting the derive onto protos/enums-as-newtypes or wrapper tuple structs; refactoring a named-field struct into a tuple struct while keeping the derive.
Related errors
- ProtoNew can only be derived for structs
- 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/26b60b16cbc7553e.
Report an issue: GitHub.