Error: BehaviorContext Class is already Registered using Uuid

I ran into a confusing bug in Lumberyard last week and as well as a workaround.

After upgrading from 1.17 to 1.18 I received a run-time error during Editor startup.

Class ‘AZStd::vector<MyProject::<MyClass*, allocator>’ is already registered using Uuid: {DDB0C655-C6C6-53EF-A27D-7D263FA0FA87}!

This often happens to me when I accidentally copy+paste to create a new component/class and forget to change the UUID registered with that class. A quick search of that UUID came up with nothing in the code-base, so I knew that couldn’t be the issue. Looking at the call-stack, I saw that this was occurring while trying to register an Event with BehaviorContext. The Event returned a list of layers, more specifically, AZStd::vectorMyProject::Player*.

If a type doesn’t already have a UUID, Lumberyard will automatically generate one. So in this case, registering the event tried to generate a UUID for the type AZStd::vectorMyProject::Player*

The assert callstack looked something like this…

AZ::Debug::Trace::Assert(const char * fileName, int line, const char * funcName, const char * format, ...)
AZ::Internal::GenericAttributes<AZ::BehaviorContext::ClassBuilder<AZStd::vector<MyProject::Player *,AZStd::allocator> > >::Attribute<enum AZ::Script::Attributes::ExcludeFlags>(AZ::Crc32 idCrc, AZ::Script::Attributes::ExcludeFlags value)
AZ::OnDemandReflection<AZStd::vector<MyProject::Player *,AZStd::allocator> >::Reflect(AZ::ReflectContext * context)
AZ::ReflectContext::ExecuteQueuedOnDemandReflections()
AZ::BehaviorContext::ClassBuilder<AZStd::vector<MyProject::Player *,AZStd::allocator> >::{dtor}()
AZ::OnDemandReflection<AZStd::vector<MyProject::Player *,AZStd::allocator> >::Reflect(AZ::ReflectContext * context)
AZ::ReflectContext::ExecuteQueuedOnDemandReflections()
AZ::BehaviorContext::EBusBuilder<AZ::EBus<MyProject::SomeEBus,MyProject::SomeEBus> >::{dtor}()
MyProject::SomeBusHandler::Reflect(AZ::ReflectContext * reflection)

The bug is that Lumberyard is accidentally auto-generating the same UUID twice when trying to reflect an AZStd::vector of pointers.

If you want to resolve this issue, you’ll need to define your own UUID so Lumberyard doesn’t incorrectly auto-generate one for you. It’s a one-line fix, using AZ_TYPE_INFO_SPECIALIZE macro… not so bad!

AZ_TYPE_INFO_SPECIALIZE(AZStd::vectorMyProject::Player*, “{5DCD16ED-BD12-4A59-A338-E8F418B71C3B}”);