stride3d/stride · error · InvalidOperationException
Failed to get ObjectDescriptor for type
Error message
Failed to get ObjectDescriptor for type [{Type.FullName}]. The member [{member}] cannot be registered as a member with the same name [{alternateName}] is already registered [{existingMember}] What it means
ObjectDescriptor.Initialize also registers each member's AlternativeNames (alias names accepted during deserialization). If an alternate name collides with an already-registered member name (or another alias), registration would be ambiguous and Initialize throws InvalidOperationException naming the type, member, colliding alternate name, and existing member.
Solutions
- Remove or rename the conflicting AlternativeName entry on the member.
- Ensure aliases are unique across all members of the type (including real member names).
- If the alias was meant to support old data migration, delete or rename the member now occupying that name.
Example fix
// before member.AlternativeNames = ["Name", "Name"]; // after member.AlternativeNames = ["Name", "LegacyName"];
Defensive patterns
Strategy: validation
Validate before calling
var all = new HashSet<string>(StringComparer.Ordinal);
foreach (var m in type.GetMembers().Where(m => m is FieldInfo or PropertyInfo))
{
if (!all.Add(m.Name)) throw new InvalidOperationException($"Alias {m.Name} collides");
foreach (var a in GetAlternativeNames(m))
if (!all.Add(a)) throw new InvalidOperationException($"Alias {a} collides");
} Try / catch
try { var desc = TypeDescriptorFactory.Default.FindDescriptor(type); }
catch (InvalidOperationException ex) when (ex.Message.Contains("AlternativeNames") || ex.Message.Contains("alternateName")) { log.LogError(ex, "Alias collision on {Type}", type); } Prevention
- Keep AlternativeNames disjoint from all member names and other aliases.
- Review alias lists after renames/migrations to remove stale entries.
- Automate an alias-uniqueness check over serializable types in tests.
When it happens
Trigger: A member declares AlternativeNames containing a string equal to another member's name, another member's alias, or its own sibling alias; raised while building the ObjectDescriptor for that type.
Common situations: Merging legacy serialized names after a rename (e.g. alias 'oldName' that matches a still-present property); mass renames where the old name was kept as a field; aliases auto-generated per naming convention colliding with actual member names.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to get ObjectDescriptor for type
- The type of collection does not have a parameterless…
- The type of dictionary does not have a parameterless…
- The order of the Asset.Id property must be lower than the…
- Event handlers can't be added or removed after the…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/819b50410eabd199.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Reflection/TypeDescriptors/ObjectDescriptor.cs:166
mapMembers = new Dictionary<string, IMemberDescriptor>(members.Length);
foreach (var member in members)
{
if (mapMembers.TryGetValue(member.Name, out var existingMember))
{
throw new InvalidOperationException("Failed to get ObjectDescriptor for type [{0}]. The member [{1}] cannot be registered as a member with the same name is already registered [{2}]".ToFormat(Type.FullName, member, existingMember));
}
mapMembers.Add(member.Name, member);
// If there is any alternative names, register them
if (member.AlternativeNames != null)
{
foreach (var alternateName in member.AlternativeNames)
{
if (mapMembers.TryGetValue(alternateName, out existingMember))
{
throw new InvalidOperationException($"Failed to get ObjectDescriptor for type [{Type.FullName}]. The member [{member}] cannot be registered as a member with the same name [{alternateName}] is already registered [{existingMember}]");
}
remapMembers ??= [];
mapMembers[alternateName] = member;
remapMembers.Add(alternateName);
}
}
}
}
public bool Contains(string memberName)
{
return mapMembers?.ContainsKey(memberName) == true;
}
protected virtual List<IMemberDescriptor> PrepareMembers()
{
if (Type == typeof(Type))View on GitHub (pinned to 96fad776d2)