diesel-rs/diesel · error
at least one `sql_type` is needed for deriving…
Error message
at least one `sql_type` is needed for deriving `AsExpression` on a structure.
What it means
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.
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`.
Example fix
// before #[derive(AsExpression)] struct MyInt(i64); // after #[derive(AsExpression)] #[diesel(sql_type = "BigInt")] struct MyInt(i64);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure a custom AsExpression struct declares its sql_type
fn validate_as_expression_struct(item: &str) -> Result<(), String> {
if item.contains("derive(AsExpression)") && !item.contains("sql_type") {
return Err("AsExpression derive requires #[diesel(sql_type = \"...\")]".into());
}
Ok(())
} Prevention
- 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
When it happens
Trigger: Annotating `#[derive(AsExpression)]` on a plain struct without any `#[diesel(sql_type = "...")]` attribute.
Common situations: 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.
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
- `#[diesel(embed)]` cannot be combined with…
- at least one `belongs_to` is needed for deriving…
- this derive can only be used on enums with exclusively…
- expected a literal expression, but got something else
- not implemented
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/e67b234c4c7865fd.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/as_expression.rs:13
use proc_macro2::TokenStream;
use quote::quote;
use syn::DeriveInput;
use syn::Result;
use syn::parse_quote;
use crate::model::Model;
use crate::util::{ty_for_foreign_derive, wrap_in_dummy_mod};
pub fn derive(item: DeriveInput) -> Result<TokenStream> {
let model = Model::from_item(&item, true, false)?;
if model.sql_types.is_empty() {
return Err(syn::Error::new(
proc_macro2::Span::mixed_site(),
"at least one `sql_type` is needed for deriving `AsExpression` on a structure.",
));
}
let struct_ty = ty_for_foreign_derive(&item, &model)?;
let sql_types = model.sql_types;
let tokens = derive_inner(
sql_types,
item.generics.clone(),
struct_ty,
model.foreign_derive,
model.not_sized,
)?;
Ok(wrap_in_dummy_mod(tokens))View on GitHub (pinned to 6fa6ed01b2)