diesel-rs/diesel · error
all fields of tuple structs must be annotated with…
Error message
all fields of tuple structs must be annotated with `#[diesel(column_name)]`
What it means
When deriving a diesel struct mapping (e.g. `Queryable`, `Insertable`) on a tuple struct, every field must carry an explicit `#[diesel(column_name = ...)]`, since tuple fields have no usable column-name source. `FieldName::Unnamed` without a column_name attribute reaches `column_name()` and raises this error at field.rs:163.
Solutions
- Annotate every field with `#[diesel(column_name = the_column)]`.
- Prefer a named struct, which infers column names from field names automatically.
- For a newtype over one column, verify the derive supports inference for your case or keep the explicit annotation.
Example fix
// before #[derive(Queryable)] pub struct UserRow(pub i32, pub String); // after #[derive(Queryable)] pub struct UserRow( #[diesel(column_name = id)] pub i32, #[diesel(column_name = name)] pub String, );
Defensive patterns
Strategy: validation
Validate before calling
// For tuple structs, every positional field needs a column_name: // struct Row(#[diesel(column_name = id)] i32, #[diesel(column_name = name)] String);
Prevention
- Prefer named structs so column names are inferred from field names.
- When using tuple structs, annotate every field with `#[diesel(column_name = ...)]`.
- Re-check annotations after converting a named struct to a tuple struct.
When it happens
Trigger: Deriving diesel traits on a tuple struct where at least one positional field lacks `#[diesel(column_name = ...)]`.
Common situations: Newtype wrappers around a single column where the author assumed the derive would infer the column; partially annotated tuple structs; converting a named struct to a tuple struct without moving the attributes.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- expected a integer literal expression, but got something…
- no `#[diesel(sql_type = ...)]` attribute provided
- `embed` and `treat_none_as_default_value` are mutually…
- `#[diesel(embed)]` cannot be combined with…
- this derive can only be used on non-unit structs
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/2c19cdf0e5ad4dc9.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/field.rs:163
treat_none_as_null,
serialize_as,
deserialize_as,
select_expression,
select_expression_type,
embed,
skip_insertion,
skip_update,
})
}
pub fn column_name(&self) -> Result<SqlIdentifier> {
let identifier = self.column_name.as_ref().map(|a| a.item.clone());
if let Some(identifier) = identifier {
Ok(identifier)
} else {
match self.name {
FieldName::Named(ref x) => Ok(x.into()),
FieldName::Unnamed(ref x) => Err(syn::Error::new(
x.span(),
"all fields of tuple structs must be annotated with `#[diesel(column_name)]`",
)),
}
}
}
pub fn ty_for_deserialize(&self) -> &Type {
if let Some(AttributeSpanWrapper { item: value, .. }) = &self.deserialize_as {
value
} else {
&self.ty
}
}
pub(crate) fn embed(&self) -> bool {
self.embed.as_ref().map(|a| a.item).unwrap_or(false)
}View on GitHub (pinned to 6fa6ed01b2)