diff --git a/scripts/errors/coll/ParamMatchingType.py b/scripts/errors/coll/ParamMatchingType.py
index f7bc4131074f115ba2238200f6f2729c27fbd236..bb88e4b8d85d7d772190b530e77d809ca8b46bc4 100644
--- a/scripts/errors/coll/ParamMatchingType.py
+++ b/scripts/errors/coll/ParamMatchingType.py
@@ -152,14 +152,16 @@ def get_correct_case(type_1, count_1, func_to_use, comm):
     return tm
 
 
-def is_combination_compatible(t1, t2, f):
-    if t1 in predefined_types and t2 in predefined_types and predefined_mpi_dtype_consants[
-        t1] == predefined_mpi_dtype_consants[t2] and not (t1 == "MPI_BYTE" or t2 == "MPI_BYTE"):
+def is_combination_compatible(a, b):
+    t1, f1, c1 = a
+    t2, f2, c2 = b
+    if t1 in predefined_types and t2 in predefined_types and predefined_mpi_dtype_consants[t1] == \
+            predefined_mpi_dtype_consants[t2] and not (t1 == "MPI_BYTE" or t2 == "MPI_BYTE"):
         # one type is just the alias of another, this is allowed
         # but BYTE may not be mixed with other types see standard section 3.3.1
         return False
 
-    return t1 != t2
+    return t1 != t2 and c1 == c2 and f1 == f2
 
 
 class InvalidComErrorColl(ErrorGenerator):
@@ -180,20 +182,33 @@ class InvalidComErrorColl(ErrorGenerator):
     def generate(self, generate_level, real_world_score_table):
 
         types = predefined_types + user_defined_types
-        combinations_to_use = []
+
+        important_cases = []
+
         for f in self.functions_to_use:
             for comm in predefined_comms + comm_creators + intercomms:
-                for i, t1 in enumerate(types):
-                    if generate_level in REAL_WORLD_FILTERING_LEVELS and not is_combination_important(real_world_score_table,
-                                                                                                f, datatype=t1.lower(),
-                                                                                                communicator=comm):
+                for t1 in types:
+                    if generate_level in REAL_WORLD_FILTERING_LEVELS and not is_combination_important(
+                            real_world_score_table,
+                            f, datatype=t1.lower(),
+                            communicator=comm):
                         continue
-                    for t2 in types[i:]:
-                        if generate_level in REAL_WORLD_FILTERING_LEVELS and not is_combination_important(
-                                real_world_score_table, f, datatype=t2.lower(), communicator=comm):
-                            continue
-                        if is_combination_compatible(t1, t2, f):
-                            combinations_to_use.append((t1, t2, f, comm))
+                    important_cases.append((t1, f, comm))
+
+        combinations_to_use = [(a, b) for a in important_cases for b in important_cases if
+                               is_combination_compatible(a, b)]
+
+        if generate_level == SUFFICIENT_REAL_WORLD_TEST_LEVEL:
+            # ensure each combination is used once but not all combinations of those
+            combinations_to_use = []
+            for a in important_cases:
+                for b in important_cases:
+                    if is_combination_compatible(a, b):
+                        combinations_to_use.append((a, b))
+                        break
+
+        # "re-format"
+        combinations_to_use = [(t1, t2, f, c) for (t1, f, c), (t2, _, _) in combinations_to_use]
 
         if generate_level == SUFFICIENT_TEST_LEVEL:
             types_checked = set()