FyroxEngine/Fyrox · error

duplicate visiting names detected!

Error message

duplicate visiting names detected!

What it means

The derive macro for Visit generates per-field visit calls keyed by name; it panics at macro-expansion time when two fields produce the same visiting name (e.g. duplicate #[visit(name = ...)] attributes or a name collision between renamed fields). Duplicate names would make serialization ambiguous, so it fails fast.

Solutions

  1. Find the two fields with the same visit name and make each #[visit(name = ...)] unique.
  2. Remove redundant explicit name attributes so fields fall back to their Rust identifiers.
  3. If collisions come from flattened/enums usage, adjust the prefix or nesting so names differ.

Example fix

// before
#[derive(Visit)]
struct S {
    #[visit(name = "hp")]
    a: f32,
    #[visit(name = "hp")]
    b: f32,
}
// after
#[derive(Visit)]
struct S {
    #[visit(name = "hp_a")]
    a: f32,
    #[visit(name = "hp_b")]
    b: f32,
}
Defensive patterns

Strategy: validation

Validate before calling

// compile-time: ensure unique visit names in your struct definitions
// cargo build will surface this panic during macro expansion;
// grep your derives first:
// grep -rn 'visit(name = ' src/ | sort | uniq -d

Prevention

When it happens

Trigger: Deriving Visit on a struct/enum where #[visit(name = "...")] attributes give two fields the same name, or field names collide after a custom rename.

Common situations: Copy-pasting field definitions with identical visit names; renaming a field's visit name to one already used by another field; refactoring structs after a version change of fyrox-core-derive.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/5ff70eba41bf0b33. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-core-derive/src/visit/utils.rs:110

                Some(new_name) => {
                    assert!(
                        !new_name.is_empty(),
                        "renaming to empty string doesn't make sense!"
                    );
                    // overwrite the field name with the specified name:
                    new_name.clone()
                }
                None => name,
            };

            (ident, name, field.optional)
        })
        .collect::<Vec<_>>();

    let mut no_dup = FxHashSet::default();
    for name in visit_args.iter().map(|(_, name, _)| name) {
        if !no_dup.insert(name) {
            panic!("duplicate visiting names detected!");
        }
    }

    let prefix = if is_struct { Some(quote!(self.)) } else { None };

    visit_args
        .iter()
        .map(|(ident, name, optional)| {
            if optional_override || *optional {
                quote! {
                    #prefix #ident.visit(#name, &mut region).ok();
                }
            } else {
                quote! {
                    if let Err(err) = #prefix #ident.visit(#name, &mut region) {
                        return Err(err);
                    }
                }

View on GitHub (pinned to 76c91aad8e)