{"record":{"id":"e67b234c4c7865fd","repo":"diesel-rs/diesel","slug":"at-least-one-sql-type-is-needed-for-deriving-as","errorCode":null,"errorMessage":"at least one `sql_type` is needed for deriving `AsExpression` on a structure.","messagePattern":"at least one `sql_type` is needed for deriving `AsExpression` on a structure\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"diesel_derives/src/as_expression.rs","lineNumber":13,"sourceCode":"use proc_macro2::TokenStream;\nuse quote::quote;\nuse syn::DeriveInput;\nuse syn::Result;\nuse syn::parse_quote;\n\nuse crate::model::Model;\nuse crate::util::{ty_for_foreign_derive, wrap_in_dummy_mod};\n\npub fn derive(item: DeriveInput) -> Result<TokenStream> {\n    let model = Model::from_item(&item, true, false)?;\n    if model.sql_types.is_empty() {\n        return Err(syn::Error::new(\n            proc_macro2::Span::mixed_site(),\n            \"at least one `sql_type` is needed for deriving `AsExpression` on a structure.\",\n        ));\n    }\n\n    let struct_ty = ty_for_foreign_derive(&item, &model)?;\n\n    let sql_types = model.sql_types;\n\n    let tokens = derive_inner(\n        sql_types,\n        item.generics.clone(),\n        struct_ty,\n        model.foreign_derive,\n        model.not_sized,\n    )?;\n\n    Ok(wrap_in_dummy_mod(tokens))","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/diesel-rs/diesel/blob/6fa6ed01b24b24248ab2a611698d0a7c6a2e9120/diesel_derives/src/as_expression.rs#L1-L31","documentation":"Deriving `AsExpression` on a struct requires the item to declare which SQL types it can be sent as, via `#[diesel(sql_type = \"...\")]` attributes (usually in a `#[diesel(...)]` block on the struct). If `model.sql_types` is empty, diesel has no way to implement `AsExpression` for a concrete SQL type and emits this compile error.","triggerScenarios":"Annotating `#[derive(AsExpression)]` on a plain struct without any `#[diesel(sql_type = \"...\")]` attribute.","commonSituations":"Creating a custom wrapper/newtype for a SQL value and forgetting that `AsExpression` must be specialized per SQL type; copying a derive line without copying the accompanying `#[diesel(...)]` attribute.","solutions":["Add `#[diesel(sql_type = \"YourSqlType\")]` on the struct (repeat the attribute for each supported SQL type).","If the struct should support many types, generate one impl per sql_type with the `diesel_for_each_tuple`-style macro or manual impls.","Check you derived the intended trait; for plain usage in queries, `Insertable`/`Queryable` may not need `AsExpression`."],"exampleFix":"// before\n#[derive(AsExpression)]\nstruct MyInt(i64);\n\n// after\n#[derive(AsExpression)]\n#[diesel(sql_type = \"BigInt\")]\nstruct MyInt(i64);","handlingStrategy":"validation","validationCode":"// Ensure a custom AsExpression struct declares its sql_type\nfn validate_as_expression_struct(item: &str) -> Result<(), String> {\n    if item.contains(\"derive(AsExpression)\") && !item.contains(\"sql_type\") {\n        return Err(\"AsExpression derive requires #[diesel(sql_type = \\\"...\\\")]\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair `#[derive(AsExpression)]` with one or more `#[diesel(sql_type = \"...\")]` lines","Copy the whole attribute block (derives + diesel attrs) when creating similar wrapper types","Look at existing diesel wrapper types in the codebase as templates"],"tags":["diesel","derive-macro","rust","sql-types"],"backgroundTag":"missing-required-argument","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"}