{"record":{"id":"e1f623f2feed62d9","repo":"apache/dubbo","slug":"arguments-types-are-different","errorCode":null,"errorMessage":"Arguments' types are different","messagePattern":"Arguments' types are different","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/merger/ArrayMerger.java","lineNumber":52,"sourceCode":"        int i = 0;\n        while (i < items.length && items[i] == null) {\n            i++;\n        }\n\n        if (i == items.length) {\n            return new Object[0];\n        }\n\n        Class<?> type = items[i].getClass().getComponentType();\n\n        int totalLen = 0;\n        for (; i < items.length; i++) {\n            if (items[i] == null) {\n                continue;\n            }\n            Class<?> itemType = items[i].getClass().getComponentType();\n            if (itemType != type) {\n                throw new IllegalArgumentException(\"Arguments' types are different\");\n            }\n            totalLen += items[i].length;\n        }\n\n        if (totalLen == 0) {\n            return new Object[0];\n        }\n\n        Object result = Array.newInstance(type, totalLen);\n\n        int index = 0;\n        for (Object[] array : items) {\n            if (array != null) {\n                System.arraycopy(array, 0, result, index, array.length);\n                index += array.length;\n            }\n        }\n        return (Object[]) result;","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/merger/ArrayMerger.java#L34-L70","documentation":"Thrown by ArrayMerger.merge() when the arrays passed in have different component types. ArrayMerger is the Merger<Object[]> used by Dubbo's group/merger feature to combine array results returned by multiple group providers into one array; all arrays must share the same component type to be concatenated.","triggerScenarios":"A service method declared with an array return type and @DubboReference(merger=...) / group merging enabled, where different provider groups return arrays of incompatible component types (e.g., one returns String[] and another Integer[]).","commonSituations":"Mixed provider implementations returning different array element types for the same interface method; a provider returning null arrays plus typed arrays in a way that resolves to differing component types; misuse of the merger feature on heterogeneous group results.","solutions":["Ensure all provider groups return arrays of the same component type for the merged method.","If heterogeneous results are expected, merge at the application layer instead of using ArrayMerger, or normalize results to a common supertype array.","Validate return-type consistency across group implementations before enabling the merger."],"exampleFix":"// before: providers return different array types -> ArrayMerger throws\n// groupA returns String[], groupB returns Object[] -> mismatch\n\n// after: all groups return the same component type\npublic interface Foo { String[] list(); } // every group returns String[]","handlingStrategy":"validation","validationCode":"// Before merging group array results, validate component types agree\nSet<Class<?>> types = Arrays.stream(items)\n    .filter(Objects::nonNull)\n    .map(a -> a.getClass().getComponentType())\n    .collect(Collectors.toSet());\nif (types.size() > 1) {\n    throw new IllegalArgumentException(\"Refusing to merge arrays of differing types: \" + types);\n}\nreturn ArrayMerger.INSTANCE.merge(items);","typeGuard":"// Guard: all non-null arrays share the same component type\nstatic boolean sameComponentType(Object[]... items) {\n    Class<?> t = null;\n    for (Object[] a : items) {\n        if (a == null) continue;\n        Class<?> c = a.getClass().getComponentType();\n        if (t == null) t = c;\n        else if (c != t) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    return ArrayMerger.INSTANCE.merge(parts);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"types are different\")) {\n        // normalize to a common array type or merge manually\n        return mergeAsObjectList(parts);\n    }\n    throw e;\n}","preventionTips":["Ensure all group providers return arrays of the same component type for merged methods.","Add a contract test verifying return-type homogeneity across groups.","If results are heterogeneous, merge at the application layer instead of via ArrayMerger."],"tags":["merger","group","cluster","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}