@@ -815,7 +815,7 @@ TEST(SubTree, SubstringTreeIDsAreNotRecursive)
815815// Test for Groot2 issue #56: duplicate _fullpath when multiple subtrees have the same name
816816// https://github.com/BehaviorTree/Groot2/issues/56
817817//
818- // When two SubTree nodes under the same parent have the same "name" attribute,
818+ // When two SubTree nodes in the same tree have the same "name" attribute,
819819// tree creation should fail with a clear error message.
820820TEST (SubTree, DuplicateSubTreeName_Groot2Issue56)
821821{
@@ -879,6 +879,48 @@ TEST(SubTree, DuplicateSubTreeName_ErrorMessage)
879879 }
880880}
881881
882+ // The duplicate check covers the whole tree, so the message must not suggest
883+ // that moving one SubTree under another parent fixes it.
884+ TEST (SubTree, DuplicateSubTreeName_DifferentParents)
885+ {
886+ // clang-format off
887+ static const char * xml_text = R"(
888+ <root BTCPP_format="4" main_tree_to_execute="MainTree">
889+ <BehaviorTree ID="MainTree">
890+ <Fallback>
891+ <Sequence>
892+ <SubTree ID="Task" name="my_task"/>
893+ </Sequence>
894+ <Sequence>
895+ <SubTree ID="Task" name="my_task"/>
896+ </Sequence>
897+ </Fallback>
898+ </BehaviorTree>
899+
900+ <BehaviorTree ID="Task">
901+ <AlwaysSuccess/>
902+ </BehaviorTree>
903+ </root>
904+ )" ;
905+ // clang-format on
906+
907+ BehaviorTreeFactory factory;
908+
909+ try
910+ {
911+ (void )factory.createTreeFromText (xml_text);
912+ FAIL () << " Expected RuntimeError to be thrown" ;
913+ }
914+ catch (const RuntimeError& e)
915+ {
916+ std::string msg = e.what ();
917+ EXPECT_TRUE (msg.find (" Duplicate SubTree path" ) != std::string::npos)
918+ << " Error message should mention 'Duplicate SubTree path'. Got: " << msg;
919+ EXPECT_TRUE (msg.find (" same parent" ) == std::string::npos)
920+ << " Error message should not limit the rule to one parent. Got: " << msg;
921+ }
922+ }
923+
882924// Test that unique names under the same parent work correctly
883925TEST (SubTree, UniqueSubTreeNames_WorksCorrectly)
884926{
0 commit comments