diesel-rs/diesel · warning
#[ ] attribute form is deprecated
Error message
#[{ident}] attribute form is deprecated What it means
This is a deprecation warning emitted by diesel's attribute parser during a `#[derive(Queryable, Identifiable, ...)]` expansion. Diesel used to accept bare attributes like `#[table_name = "users"]` / `#[primary_key(id)]` directly on the derived struct; these now must be namespaced as `#[diesel(table_name = "users")]`. The `warn!` macro wraps the identifier's span and message so the compiler points at the exact offending attribute. It does not fail the build — the old form still works until removed.
Solutions
- Prefix every diesel attribute with `diesel::`, e.g. change `#[table_name = "users"]` to `#[diesel(table_name = "users")]`
- Do the same for related attributes: `#[diesel(primary_key(id))]`, `#[diesel(belongs_to(User))]`, `#[diesel(column_name = x)]`
- Read the `= help:` note attached to the warning — it states the exact replacement form for that attribute
- Run `cargo fix` or manually sweep the crate with `cargo build 2>&1 | grep deprecated` to find all occurrences
Example fix
// before
#[derive(Queryable, Identifiable)]
#[table_name = "users"]
#[primary_key(id)]
pub struct User { pub id: i32, pub name: String }
// after
#[derive(Queryable, Identifiable)]
#[diesel(table_name = users)]
#[diesel(primary_key(id))]
pub struct User { pub id: i32, pub name: String } Defensive patterns
Strategy: validation
Validate before calling
// grep-style check a team can run in CI to catch old attribute forms before building grep -rnE '#\[(table_name|primary_key|belongs_to|column_name|foreign_key|select_expression)[ (=]' src/ \ && echo 'Deprecated diesel attribute form found — namespace with #[diesel(...)]' && exit 1 || true
Prevention
- Always namespace diesel derive attributes as `#[diesel(...)]` in new code
- Upgrade-prepare: sweep the codebase for bare `#[table_name]`, `#[primary_key]`, `#[belongs_to]`, `#[column_name]` after bumping diesel
- Add the CI grep/lint above to reject legacy attribute forms at PR time
- Copy derive structs from the current diesel docs/examples, not old tutorials
When it happens
Trigger: Deriving diesel traits on a struct that still uses the old un-namespaced attribute syntax, e.g. `#[table_name = "posts"]`, `#[primary_key(id)]`, `#[belongs_to(User, foreign_key = "user_id")]`, `#[column_name = "x"]` without the `#[diesel(...)]` prefix. Occurs during `cargo build`/`cargo check` whenever the parser hits such an attribute.
Common situations: Upgrading diesel from 1.x/early 2.0 to 2.x where attribute namespacing became required by convention; code generated by older tutorials or books; copy-pasted derive structs from older projects; lint-clean CI builds surfacing the warnings after a dependency bump.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- , the correct format is `#[aggregate]
- , the correct format is `#[skip_return_type_helper]
- , the correct format is `#[window]
- unexpected token after positional `#[variadic(..)]`
- expect `last_arguments`
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/15693d3d9405aa0b.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_attribute_parser/src/deprecated/mod.rs:54
#[cfg(all(not(feature = "without-deprecated"), feature = "with-deprecated"))]
mod impl_deprecated {
use super::{ParseDeprecated, ParseStream, Result};
use crate::deprecated::belongs_to::parse_belongs_to;
use crate::deprecated::changeset_options::parse_changeset_options;
use crate::deprecated::postgres_type::parse_postgres_type;
use crate::deprecated::primary_key::parse_primary_key;
use crate::deprecated::utils::parse_eq_and_lit_str;
use crate::notes::{
COLUMN_NAME_NOTE, MYSQL_TYPE_NOTE, SQL_TYPE_NOTE, SQLITE_TYPE_NOTE, TABLE_NAME_NOTE,
};
use crate::parsers::{MysqlType, PostgresType, SqliteType};
use crate::{FieldAttr, StructAttr};
use proc_macro2::Span;
use syn::Ident;
macro_rules! warn {
($ident: expr_2021, $help: expr_2021) => {
warn(
$ident.span(),
&format!("#[{}] attribute form is deprecated", $ident),
$help,
);
};
}
impl ParseDeprecated for StructAttr {
fn parse_deprecated(input: ParseStream) -> Result<Option<Self>> {
let name: Ident = input.parse()?;
let name_str = name.to_string();
match &*name_str {
"table_name" => {
let lit_str = parse_eq_and_lit_str(name.clone(), input, TABLE_NAME_NOTE)?;
warn!(
name,
&format!("use `#[diesel(table_name = {})]` instead", lit_str.value())View on GitHub (pinned to 6fa6ed01b2)