{"record":{"id":"7c12ad611f46006b","repo":"apache/dubbo","slug":"args-length-types-length","errorCode":null,"errorMessage":"args.length != types.length","messagePattern":"args\\.length != types\\.length","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java","lineNumber":113,"sourceCode":"            Short.class,\n            Integer.class,\n            Long.class,\n            Float.class,\n            Double.class,\n            Boolean.class,\n            Character.class);\n\n    public static Object[] generalize(Object[] objs) {\n        Object[] dests = new Object[objs.length];\n        for (int i = 0; i < objs.length; i++) {\n            dests[i] = generalize(objs[i]);\n        }\n        return dests;\n    }\n\n    public static Object[] realize(Object[] objs, Class<?>[] types) {\n        if (objs.length != types.length) {\n            throw new IllegalArgumentException(\"args.length != types.length\");\n        }\n\n        Object[] dests = new Object[objs.length];\n        for (int i = 0; i < objs.length; i++) {\n            dests[i] = realize(objs[i], types[i]);\n        }\n\n        return dests;\n    }\n\n    public static Object[] realize(Object[] objs, Class<?>[] types, Type[] gtypes) {\n        if (objs.length != types.length || objs.length != gtypes.length) {\n            throw new IllegalArgumentException(\"args.length != types.length\");\n        }\n        Object[] dests = new Object[objs.length];\n        for (int i = 0; i < objs.length; i++) {\n            dests[i] = realize(objs[i], types[i], gtypes[i]);\n        }","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java#L95-L131","documentation":"PojoUtils.realize(Object[] objs, Class<?>[] types) is the reverse-generalization entry point: it converts generic (often Map/Primitive) representations back into typed Java objects. It enforces that the argument array and the target type array have the same length. If they differ, there is no way to align each argument to its target type, so it throws immediately.","triggerScenarios":"Calling PojoUtils.realize(objs, types) where objs.length != types.length. This typically happens inside Dubbo's generic invocation path ($invoke) where the serialized arguments and the declared parameter types from the service metadata must correspond one-to-one.","commonSituations":"A generic Dubbo RPC call where the number of arguments sent by the consumer does not match the number of parameter types declared in the provider interface. This can occur with version mismatches between consumer and provider interfaces, or when a generic caller builds the argument/type arrays manually and miscounts.","solutions":["Verify that the argument array and the parameter type array passed to realize (or to $invoke/generic invocation) have the same length.","Check for consumer/provider interface version mismatch where a method signature changed (added/removed a parameter).","Ensure null arguments are still represented as array elements (not omitted), since null is a valid argument but a missing slot changes the length.","Log both arrays' lengths and contents before the call to pinpoint the mismatch source."],"exampleFix":"// before\nObject[] args = {\"hello\"};\nClass<?>[] types = {String.class, Integer.class};\nPojoUtils.realize(args, types); // throws: 1 != 2\n// after\nObject[] args = {\"hello\", null};\nClass<?>[] types = {String.class, Integer.class};\nPojoUtils.realize(args, types);","handlingStrategy":"validation","validationCode":"// Validate array lengths match before calling realize\nif (objs == null || types == null || objs.length != types.length) {\n    throw new IllegalArgumentException(\n        \"objs.length (\" + (objs == null ? \"null\" : objs.length)\n        + \") must equal types.length (\" + (types == null ? \"null\" : types.length) + \")\");\n}\nPojoUtils.realize(objs, types);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive both arrays from the same Method: types from getParameterTypes() and args from the invocation context.","In generic invocation ($invoke), always pass a parameterTypes array matching the argument count.","Add integration tests that verify argument/type alignment before deployment."],"tags":["pojo","generic-invocation","rpc","argument-mismatch"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}