{"record":{"id":"ba41a4b6739e87fb","repo":"diesel-rs/diesel","slug":"this-derive-can-only-be-used-on-non-unit-structs","errorCode":null,"errorMessage":"this derive can only be used on non-unit structs","messagePattern":"this derive can only be used on non-unit structs","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"diesel_derives/src/model.rs","lineNumber":61,"sourceCode":"        item: &DeriveInput,\n        allow_unit_structs: bool,\n        allow_multiple_table: bool,\n    ) -> Result<Self> {\n        let DeriveInput {\n            data, ident, attrs, ..\n        } = item;\n\n        let fields = match *data {\n            Data::Struct(DataStruct {\n                fields: Fields::Named(FieldsNamed { ref named, .. }),\n                ..\n            }) => Some(named),\n            Data::Struct(DataStruct {\n                fields: Fields::Unnamed(FieldsUnnamed { ref unnamed, .. }),\n                ..\n            }) => Some(unnamed),\n            _ if !allow_unit_structs => {\n                return Err(syn::Error::new(\n                    proc_macro2::Span::mixed_site(),\n                    \"this derive can only be used on non-unit structs\",\n                ));\n            }\n            _ => None,\n        };\n\n        let mut table_names = vec![];\n        let mut primary_key_names = vec![Ident::new(\"id\", Span::mixed_site())];\n        let mut treat_none_as_default_value = None;\n        let mut treat_none_as_null = None;\n        let mut belongs_to = vec![];\n        let mut sql_types = vec![];\n        let mut aggregate = false;\n        let mut not_sized = false;\n        let mut enum_type = false;\n        let mut foreign_derive = false;\n        let mut mysql_type = None;","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/diesel-rs/diesel/blob/6fa6ed01b24b24248ab2a611698d0a7c6a2e9120/diesel_derives/src/model.rs#L43-L79","documentation":"Diesel struct-mapping derives require named or tuple structs with at least one field; unit structs carry no fields and thus cannot map to table columns. `from_item` in model.rs raises this error at the mixed_site span when the input is not a struct with fields (or is a unit struct while `allow_unit_structs` is false).","triggerScenarios":"Deriving `Queryable`, `Identifiable`, `Associations`, `Insertable`, etc. on a unit struct like `struct User;`, or on an enum/union where the derive doesn't accept it.","commonSituations":"Marker/phantom types accidentally carrying diesel derives; refactoring a struct to `struct X;` leaving derives behind; applying a struct derive to an enum.","solutions":["Give the struct at least one field corresponding to a table column.","Remove the diesel derive if the type is only a marker.","If mapping a single column, use a tuple/newtype struct with a field, not a unit struct."],"exampleFix":"// before\n#[derive(Queryable)]\nstruct UserId;\n\n// after\n#[derive(Queryable)]\nstruct UserId(#[diesel(column_name = id)] i32);","handlingStrategy":"validation","validationCode":"// Diesel struct derives need a struct with fields:\n// struct Good { id: i32 }        // OK\n// struct Good(i32);              // OK (tuple fields need column_name)\n// struct Unit;                   // FAILS\n// let _ = std::mem::size_of::<T>(); // companion check: unit structs compile but derive-fail","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not put diesel derives on marker/phantom unit structs.","After refactoring a struct to unit form, remove its diesel derives.","Use enums only with the enum-specific diesel derives, not struct-mapping derives."],"tags":["proc-macro","derive","unit-struct","compile-time"],"backgroundTag":"invalid-argument-value","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"}