{"record":{"id":"73a58bc5d978e872","repo":"apache/dubbo","slug":"can-not-merge-result-because-missing-method-mer","errorCode":null,"errorMessage":"Can not merge result because missing method [ {merger} ] in class [ {returnType.getName()} ]","messagePattern":"Can not merge result because missing method \\[ (.+?) \\] in class \\[ (.+?) \\]","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"error","filePath":"dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java","lineNumber":154,"sourceCode":"        }\n\n        if (resultList.isEmpty()) {\n            return AsyncRpcResult.newDefaultAsyncResult(invocation);\n        } else if (resultList.size() == 1) {\n            return AsyncRpcResult.newDefaultAsyncResult(resultList.get(0).getValue(), invocation);\n        }\n\n        if (returnType == void.class) {\n            return AsyncRpcResult.newDefaultAsyncResult(invocation);\n        }\n\n        if (merger.startsWith(\".\")) {\n            merger = merger.substring(1);\n            Method method;\n            try {\n                method = returnType.getMethod(merger, returnType);\n            } catch (NoSuchMethodException | NullPointerException e) {\n                throw new RpcException(\"Can not merge result because missing method [ \" + merger + \" ] in class [ \"\n                        + returnType.getName() + \" ]\");\n            }\n            if (!Modifier.isPublic(method.getModifiers())) {\n                method.setAccessible(true);\n            }\n            result = resultList.remove(0).getValue();\n            try {\n                if (method.getReturnType() != void.class\n                        && method.getReturnType().isAssignableFrom(result.getClass())) {\n                    for (Result r : resultList) {\n                        result = method.invoke(result, r.getValue());\n                    }\n                } else {\n                    for (Result r : resultList) {\n                        method.invoke(result, r.getValue());\n                    }\n                }\n            } catch (Exception e) {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java#L136-L172","documentation":"Thrown by MergeableClusterInvoker when the configured merger starts with '.', telling Dubbo to merge results by reflecting a method on the return type, but that method (named by the merger substring) taking a single returnType argument does not exist or the returnType is null. NoSuchMethodException (method missing) or NullPointerException (returnType null) both surface as this RpcException.","triggerScenarios":"Method-level or interface-level config merger=\".someMethod\" where the service method's return type has no public someMethod(ReturnType) signature; or the invoked method returns void/void-compatible so returnType resolves to null (NPE on returnType.getMethod); or a typo in the method name after the dot.","commonSituations":"Configuring merger=\".addAll\" on a service whose return type is a custom DTO without such a combining method; returning void from a method that has a merger; renaming a merge method in code but not updating the dubbo config; copy-pasting a merger config from another service with a different return type.","solutions":["Add a public method named exactly <merger>(ReturnType) on the return type that combines two instances and returns the merged result.","Correct the method name in the merger config to match an existing combining method (watch for typos and case).","If the method legitimately returns void or you want SPI-based merging, remove the leading dot and use a named Merger extension or merger=\"true\" instead.","Verify the invoked method's declared return type matches the type the merge method operates on."],"exampleFix":"// before: return type lacks a combining method\npublic class Stats { /* no merge(Stats) */ }\n<dubbo:method name=\"getStats\" merger=\".merge\"/>\n\n// after: add the public combining method\npublic class Stats {\n    public Stats merge(Stats other) { /* combine fields */ return this; }\n}","handlingStrategy":"validation","validationCode":"// Validate the merge method exists BEFORE configuring the service\nMethod m;\ntry {\n    m = ReturnType.class.getMethod(mergerName.substring(1), ReturnType.class);\n} catch (NoSuchMethodException e) {\n    throw new IllegalStateException(\"return type lacks merge method \" + mergerName, e);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a startup/unit test asserting the configured dot-merger method exists on the return type.","Never apply a dot-merger to a void-returning method.","Keep merger config and the merge method name in lockstep when renaming."],"tags":["cluster","mergeable","reflection","merger","config"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}