{"record":{"id":"7da82dd7b278b6bf","repo":"PyO3/pyo3","slug":"name-may-only-be-specified-once","errorCode":null,"errorMessage":"`name` may only be specified once","messagePattern":"`name` may only be specified once","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"pyo3-macros-backend/src/pyclass.rs","lineNumber":412,"sourceCode":"            set: None,\n            name: None,\n        };\n\n        for option in take_pyo3_options(attrs)? {\n            match option {\n                FieldPyO3Option::Get(kw) => {\n                    if options.get.replace(Annotated::Field(kw)).is_some() {\n                        return Err(syn::Error::new(kw.span(), UNIQUE_GET));\n                    }\n                }\n                FieldPyO3Option::Set(kw) => {\n                    if options.set.replace(Annotated::Field(kw)).is_some() {\n                        return Err(syn::Error::new(kw.span(), UNIQUE_SET));\n                    }\n                }\n                FieldPyO3Option::Name(name) => {\n                    if options.name.replace(name).is_some() {\n                        return Err(syn::Error::new(options.name.span(), UNIQUE_NAME));\n                    }\n                }\n            }\n        }\n\n        Ok(options)\n    }\n}\n\nfn get_class_python_name<'a>(cls: &'a Ident, args: &'a PyClassArgs) -> Cow<'a, Ident> {\n    args.options\n        .name\n        .as_ref()\n        .map(|name_attr| Cow::Borrowed(&name_attr.value.0))\n        .unwrap_or_else(|| Cow::Owned(cls.unraw()))\n}\n\n#[cfg(feature = \"experimental-inspect\")]","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/PyO3/pyo3/blob/ac9b6899d348be4d54614d060dea53a645a12e36/pyo3-macros-backend/src/pyclass.rs#L394-L430","documentation":"pyo3 rejects a `name = \"...\"` option given more than once to the same pyclass or field. The class/field name slot holds a single value; a second `name` triggers this syn::Error at the slot's span (i.e. pointing at the first `name`, since `options.name.span()` is used).","triggerScenarios":"`#[pyclass(name = \"A\", name = \"B\")]` or a field attribute containing two `name = ...` entries, possibly via concatenated attribute fragments.","commonSituations":"Refactors where a Python-visible name was renamed but the old `name` entry left behind; tooling that injects `name` alongside a user-specified one.","solutions":["Keep only one `name = \"...\"` per pyclass/field","Decide the intended Python name and delete the other","If tooling injects `name`, remove the manual one or configure the tool"],"exampleFix":"// before\n#[pyclass(name = \"Point\", name = \"PyPoint\")]\nstruct Point;\n// after\n#[pyclass(name = \"PyPoint\")]\nstruct Point;","handlingStrategy":"validation","validationCode":"// Ensure a single name entry per pyclass/field attribute\nassert_eq!(attr_string.matches(\"name =\").count(), 1, \"duplicate name option\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One `name = \"...\"` per class/field only","Remove stale name entries after renames","Let CI grep catch multiple `name =` in one attribute"],"tags":["rust","pyo3","macro","compile-time"],"backgroundTag":"duplicate-attribute-option","analyzedSha":"ac9b6899d348be4d54614d060dea53a645a12e36","analyzedAt":"2026-09-05T09:20:35.319Z","contentChangedAt":"2026-09-05T09:20:35.319Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}