diesel-rs/diesel · error · syn::Error
`#[diesel(embed)]` cannot be combined with…
Error message
`#[diesel(embed)]` cannot be combined with `#[diesel(serialize_as)]`
What it means
In the `Insertable` derive, `#[diesel(embed)]` splices a whole nested set of columns, while `#[diesel(serialize_as)]` converts a single field's type; applying both to one field is incoherent, so the derive returns this error at insertable.rs:156.
Solutions
- Remove one of the two attributes — they cannot coexist on the same field.
- If the field should be a single converted column, keep `serialize_as` and drop `embed`.
- If the field should splice multiple columns, keep `embed` and do the type conversion inside the embedded type's own derive.
Example fix
// before
struct NewPost {
#[diesel(embed, serialize_as = JsonMeta)]
meta: Meta,
}
// after
struct NewPost {
#[diesel(embed)]
meta: Meta, // do conversion inside Meta's own derives
} Defensive patterns
Strategy: validation
Validate before calling
// A field is either embedded or converted via serialize_as — never both: // #[diesel(embed)] // splice columns // #[diesel(serialize_as = T)] // convert one column // #[diesel(embed, serialize_as = T)] // FAILS
Prevention
- Decide per field: single converted column (serialize_as) vs. column splicing (embed).
- Move type conversion into the embedded type's own derives when both are needed.
- Grep derive attributes for accidental double annotations after edits.
When it happens
Trigger: A single field annotated with both `#[diesel(embed)]` and `#[diesel(serialize_as = SomeType)]`.
Common situations: Adding a serialize_as conversion to a field that was already embedded; combining wrapper-type conversion with nested insertable splicing in one attribute edit.
Related errors
- `embed` and `treat_none_as_default_value` are mutually…
- expected a integer literal expression, but got something…
- no `#[diesel(sql_type = ...)]` attribute provided
- all fields of tuple structs must be annotated 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/c3dae145fe274ea7.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/insertable.rs:156
field,
table_name,
ty,
treat_none_as_default_value,
)?);
field_ty_bounds.push(generate_field_bound(
field,
table_name,
ty,
treat_none_as_default_value,
None,
&mut field_ty_bounds_guard,
)?);
generate_borrowed_insert = false; // as soon as we hit one field with #[diesel(serialize_as)] there is no point in generating the impl of Insertable for borrowed structs
}
(Some(AttributeSpanWrapper { attribute_span, .. }), true) => {
return Err(syn::Error::new(
*attribute_span,
"`#[diesel(embed)]` cannot be combined with `#[diesel(serialize_as)]`",
));
}
}
}
let field_ty_bounds = field_ty_bounds
.into_iter()
.filter_map(|(type_to_check, bound)| {
filter_bounds(&field_ty_bounds_guard, type_to_check, bound)
});
let insert_owned = quote! {
impl #impl_generics diesel::insertable::Insertable<#table_name::table> for #struct_name #ty_generics
where
#where_clause
#(#field_ty_bounds,)*
{View on GitHub (pinned to 6fa6ed01b2)