diesel-rs/diesel · error · syn::Error
references are not supported in `Queryable` types consider…
Error message
references are not supported in `Queryable` types
consider using `std::borrow::Cow<'{}, {}>` instead What it means
The `#[derive(Queryable)]` proc macro in diesel_derives generates code that checks each field type of the struct against the query row. Fields declared as references (e.g. `&'a str`) cannot be supported because generated deserialization code cannot produce borrows with valid lifetimes from the row. The macro explicitly rejects `syn::Type::Reference` fields in `to_field_ty_bound` and suggests `std::borrow::Cow` as a replacement that can own or borrow data.
Solutions
- Change the reference field to an owned type (`String`, `Vec<u8>`) or `std::borrow::Cow<'a, str>`.
- If you must avoid allocation, deserialize to owned types and borrow afterwards, or use `sql_types::Text` mappings with owned `String`.
- If the reference is unnecessary, drop the lifetime entirely and use owned field types.
Example fix
// before
#[derive(Queryable)]
struct User<'a> {
name: &'a str,
}
// after
use std::borrow::Cow;
#[derive(Queryable)]
struct User<'a> {
name: Cow<'a, str>,
}
// or simply: struct User { name: String } Defensive patterns
Strategy: type-guard
Validate before calling
// Compile-time check: this fails to compile if any field is a reference
fn assert_no_refs<T>() {}
struct User { name: String }
fn main() { assert_no_refs::<User>(); } Type guard
fn has_reference_fields<'a>(s: &'a str) -> bool { std::mem::size_of_val(&s) == std::mem::size_of::<&'a str>() && false } // Prefer: simply use owned or Cow<'a, T> field types so the derive always compiles Prevention
- Use owned types (String, Vec<u8>) or Cow<'a, T> in any struct deriving Queryable/Selectable.
- Never copy struct shapes with reference fields into diesel derives.
- Run cargo check early; this is a compile-time error, so CI catches it immediately.
When it happens
Trigger: Deriving `Queryable` (or `QueryableByName`/`Selectable` checked via `generate_check_function`) on a struct containing a reference-typed field such as `name: &'a str` or `&'a [u8]`.
Common situations: Developers porting structs that borrowed from input data, trying to avoid allocations in query results, or copying a struct shape that works with serde but not with diesel's `Queryable` derive.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- invalid variadic argument count: not enough function…
- Failed to create embedded migrations instance
- expected attribute `name` help: the correct format looks…
- unknown attribute, expected
- unexpected end of input, expected `=` help: the correct…
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/97d419a1feb72bf1.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/selectable.rs:150
let where_clause = where_clause.get_or_insert_with(|| parse_quote!(where));
for field_check in field_check_bound {
where_clause.predicates.push(field_check);
}
Ok(quote::quote! {
fn #function_name #original_impl_generics()
#where_clause
{}
})
}
fn to_field_ty_bound(field_ty: &syn::Type) -> Result<TokenStream> {
match field_ty {
syn::Type::Reference(r) => {
use crate::quote::ToTokens;
// references are not supported for checking for now
//
// (How ever you can even have references in a `Queryable` struct anyway)
Err(syn::Error::new(
field_ty.span(),
format!(
"references are not supported in `Queryable` types\n\
consider using `std::borrow::Cow<'{}, {}>` instead",
r.lifetime
.as_ref()
.expect("It's a struct field so it must have a named lifetime")
.ident,
r.elem.to_token_stream()
),
))
}
field_ty => Ok(quote::quote! {
#field_ty
}),
}
}
View on GitHub (pinned to 6fa6ed01b2)