On file [Engine\Source\Runtime\AIModule\Private\EnvironmentQuery\EnvQueryManager.cpp:812], function UEnvQueryManager::CreateQueryInstance() uses StaticDuplicateObject() to create a new UEnvQuery* (duplicated from the asset provided provided as template) and store it in an internal FEnvQueryInstanceCache. The name of the duplicated object is calculated beforehand from the template classname and fname, with an added suffix from the run mode.
The calculated name must be unique, as noted on CL 38630344 and its related PR #12397, which addressed [Link Removed]. That CL attempted to use function MakeUniqueObjectName() to guarantee uniqueness when multiple instances are created from the same template. However, it did not account for the runmode suffix, which was left to be appended to the result of MakeUniqueObjectName(). This ends up fooling MakeUniqueObjectName(), because its result is never actually used to create an object. The example below shows how this situation can happen quite easily:
Consider two Environment Query assets "MyEnvQuery" and "MyEnvQuery_2" on the content browser, both of which are used to create runtime queries. When "MyEnvQuery" is passed to MakeUniqueObjectName(), it returns "MyEnvQuery_0" as a unique name. But the actual object is created with a suffix, for example "MyEnvQuery_0_SingleResult". Later, when "MyEnvQuery_2" is passed to MakeUniqueObjectName(), it once again returns "MyEnvQuery_0" (since that name remains unused). As a result, StaticDuplicateObject() is called again with "MyEnvQuery_0_SingleResult", which makes it return the same object as before instead of a new duplicate as intended. This will result in two different cache entries pointing to that same object. Moreover, when "UEnvQueryOption* LocalOption" and "UEnvQueryGenerator* LocalGenerator" are created further down on UEnvQueryManager::CreateQueryInstance(), they will be placed on that same UEnvQuery template, one overriding the other.
One possible solution is to preappend the runmode enum string before passing the result to MakeUniqueObjectName(). Perhaps another option (needs testing) would be to simply not append the runmode enum string at all.
1. Place a breakpoint on [Engine\Source\Runtime\AIModule\Private\EnvironmentQuery\EnvQueryManager.cpp:812], where function UEnvQueryManager::CreateQueryInstance() creates "UEnvQuery* LocalTemplate" by calling StaticDuplicateObject()
2. Create two Environment Query assets "MyEQSQuery" and "MyEQSQuery_2". Add a generator to each one.
3. Create a BP "MyEQSTestingPawn" derived from EQSTestingPawn
4. Add an instance of "MyEQSTestingPawn" to the level
4.1. On the details panel, search for "EQS" and set "Query Template" to "MyEQSQuery"
4.2. The breakpoint should be hit. Take note of the value of "Template.NamePrivate" and "NewInstanceName", and of the address of the returned "UEnvQuery* LocalTemplate" object.
5. Add another instance of "MyEQSTestingPawn" to the level
5.1. On the details panel, search for "EQS" and set "Query Template" to "MyEQSQuery_2"
5.2. The breakpoint should be hit. Take note of the value of "Template.NamePrivate" and "NewInstanceName", and of the address of the returned "UEnvQuery* LocalTemplate" object.
5.3. Note that "NewInstanceName" was the same in both cases, which results in StaticDuplicateObject() also returning the same "UEnvQuery* LocalTemplate" object both times.
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-309265 in the post.