PyO3/pyo3 · error · syn::Error
`name` may only be specified once
Error message
`name` may only be specified once
What it means
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).
Source
Thrown at pyo3-macros-backend/src/pyclass.rs:412
set: None,
name: None,
};
for option in take_pyo3_options(attrs)? {
match option {
FieldPyO3Option::Get(kw) => {
if options.get.replace(Annotated::Field(kw)).is_some() {
return Err(syn::Error::new(kw.span(), UNIQUE_GET));
}
}
FieldPyO3Option::Set(kw) => {
if options.set.replace(Annotated::Field(kw)).is_some() {
return Err(syn::Error::new(kw.span(), UNIQUE_SET));
}
}
FieldPyO3Option::Name(name) => {
if options.name.replace(name).is_some() {
return Err(syn::Error::new(options.name.span(), UNIQUE_NAME));
}
}
}
}
Ok(options)
}
}
fn get_class_python_name<'a>(cls: &'a Ident, args: &'a PyClassArgs) -> Cow<'a, Ident> {
args.options
.name
.as_ref()
.map(|name_attr| Cow::Borrowed(&name_attr.value.0))
.unwrap_or_else(|| Cow::Owned(cls.unraw()))
}
#[cfg(feature = "experimental-inspect")]View on GitHub (pinned to ac9b6899d3)
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
Example fix
// before #[pyclass(name = "Point", name = "PyPoint")] struct Point; // after #[pyclass(name = "PyPoint")] struct Point;
Defensive patterns
Strategy: validation
Validate before calling
// Ensure a single name entry per pyclass/field attribute
assert_eq!(attr_string.matches("name =").count(), 1, "duplicate name option"); Prevention
- One `name = "..."` per class/field only
- Remove stale name entries after renames
- Let CI grep catch multiple `name =` in one attribute
When it happens
Trigger: `#[pyclass(name = "A", name = "B")]` or a field attribute containing two `name = ...` entries, possibly via concatenated attribute fragments.
Common situations: Refactors where a Python-visible name was renamed but the old `name` entry left behind; tooling that injects `name` alongside a user-specified one.
Related errors
- `get` may only be specified once
- `set` may only be specified once
- missing `message` in `warn` attribute
- Python doc may not contain nul byte, found nul at position {
- Neither abi3 or abi3t features are enabled
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/7da82dd7b278b6bf.
Report an issue: GitHub.