{"record":{"id":"c3dae145fe274ea7","repo":"diesel-rs/diesel","slug":"diesel-embed-cannot-be-combined-with-dies-c3dae1","errorCode":null,"errorMessage":"`#[diesel(embed)]` cannot be combined with `#[diesel(serialize_as)]`","messagePattern":"`#\\[diesel\\(embed\\)\\]` cannot be combined with `#\\[diesel\\(serialize_as\\)\\]`","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"diesel_derives/src/insertable.rs","lineNumber":156,"sourceCode":"                    field,\n                    table_name,\n                    ty,\n                    treat_none_as_default_value,\n                )?);\n\n                field_ty_bounds.push(generate_field_bound(\n                    field,\n                    table_name,\n                    ty,\n                    treat_none_as_default_value,\n                    None,\n                    &mut field_ty_bounds_guard,\n                )?);\n\n                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\n            }\n            (Some(AttributeSpanWrapper { attribute_span, .. }), true) => {\n                return Err(syn::Error::new(\n                    *attribute_span,\n                    \"`#[diesel(embed)]` cannot be combined with `#[diesel(serialize_as)]`\",\n                ));\n            }\n        }\n    }\n\n    let field_ty_bounds = field_ty_bounds\n        .into_iter()\n        .filter_map(|(type_to_check, bound)| {\n            filter_bounds(&field_ty_bounds_guard, type_to_check, bound)\n        });\n    let insert_owned = quote! {\n        impl #impl_generics diesel::insertable::Insertable<#table_name::table> for #struct_name #ty_generics\n        where\n            #where_clause\n            #(#field_ty_bounds,)*\n        {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/diesel-rs/diesel/blob/6fa6ed01b24b24248ab2a611698d0a7c6a2e9120/diesel_derives/src/insertable.rs#L138-L174","documentation":"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.","triggerScenarios":"A single field annotated with both `#[diesel(embed)]` and `#[diesel(serialize_as = SomeType)]`.","commonSituations":"Adding a serialize_as conversion to a field that was already embedded; combining wrapper-type conversion with nested insertable splicing in one attribute edit.","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."],"exampleFix":"// before\nstruct NewPost {\n  #[diesel(embed, serialize_as = JsonMeta)]\n  meta: Meta,\n}\n\n// after\nstruct NewPost {\n  #[diesel(embed)]\n  meta: Meta, // do conversion inside Meta's own derives\n}","handlingStrategy":"validation","validationCode":"// A field is either embedded or converted via serialize_as — never both:\n// #[diesel(embed)]               // splice columns\n// #[diesel(serialize_as = T)]    // convert one column\n// #[diesel(embed, serialize_as = T)] // FAILS","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["proc-macro","derive","insertable","attribute-conflict","compile-time"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"6fa6ed01b24b24248ab2a611698d0a7c6a2e9120","analyzedAt":"2026-09-07T01:50:13.074Z","contentChangedAt":"2026-09-07T01:50:13.074Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}