dbt-labs/dbt-core · error · syn::Error
Unnamed field not supported
Error message
Unnamed field not supported
What it means
The ProtoNew derive macro generates a `new()` constructor from a struct's fields, and it requires every field to be named so it can emit a matching named parameter. It is a compile-time (proc-macro) error raised when the derived struct contains tuple-style or unit fields, which have no identifier to turn into a constructor argument.
Source
Thrown at crates/proto-rust-macros/src/lib.rs:69
},
_ => {
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)?;
let param_ident = field_ident.clone();
// Collect doc for this field
if let Some(doc) = extract_field_doc(&field.attrs) {
let name = field_ident.to_string();
let arg_doc = format!("* `{name}` - {doc}");
arg_docs.push(arg_doc);
}
if let Some(enum_path) = is_enum {
// Replace i32 in the outer shape with enum path for the parameter type,
// and create an initializer that converts enum(s) back to i32.
let (param_ty_tokens, init_expr) =
map_enum_param_and_init(&field.ty, &enum_path, ¶m_ident)?;
params.push(quote! { #param_ident: #param_ty_tokens });View on GitHub (pinned to 0267ce9170)
Solutions
- Convert the struct to use named fields: `struct Msg(i32);` -> `struct Msg { value: i32 }`.
- If the type is a genuine newtype wrapper, remove `#[derive(ProtoNew)]` and implement `new()` manually.
- Keep prost-generated message structs untouched and derive ProtoNew only on structs produced from .proto definitions, which always have named fields.
Example fix
// before
#[derive(ProtoNew)]
struct MyMessage(i32);
// after
#[derive(ProtoNew)]
struct MyMessage {
value: i32,
} Defensive patterns
Strategy: validation
Validate before calling
// compile-time check: derive fails fast if any field is unnamed
fn assert_named_fields<T>() {}
// Ensure struct shape before deriving:
// struct Msg { id: i32 } // all fields must be `name: Type` Prevention
- Only apply ProtoNew to structs with all-named fields
- Never hand-write tuple structs for prost messages
- Let code review/lint flag derive attributes on newtype wrappers
When it happens
Trigger: Applying #[derive(ProtoNew)] to a struct declared with unnamed fields (e.g. `struct Msg(i32);`) or unit variants/fields (`struct Msg;`) instead of named fields (`struct Msg { id: i32 }`).
Common situations: Hand-written prost message structs that mimic tuple structs; copied Rust code (like newtype wrappers) that happens to carry the derive; code generated from a .proto with unusual shapes then hand-edited into tuple form.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ProtoNew only supports structs with named fields
- ProtoNew can only be derived for structs
- 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/627385b0e3a30b07.
Report an issue: GitHub.