{"record":{"id":"65770af2fbbf6255","repo":"pxb1988/dex2jar","slug":"can-t-cast-to","errorCode":null,"errorMessage":"can't cast  to ","messagePattern":"can't cast  to ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java","lineNumber":435,"sourceCode":"                return  mv==null?null: new ReplaceMethodVisitor(mv);\n            }\n            class ReplaceMethodVisitor extends MethodVisitor {\n                public ReplaceMethodVisitor(MethodVisitor mv) {\n                    super(ASM9, mv);\n                }\n\n                @Override\n                public void visitMethodInsn(int opcode, String owner, String name, String desc,\n                                            boolean isInterface) {\n                    MtdInfo mapTo = findTargetMethod(\"L\" + owner + \";\", name, desc);\n                    if (mapTo != null) {\n                        boolean isStatic = opcode == INVOKESTATIC;\n                        Type orgRet = Type.getReturnType(desc);\n                        Type[] orgArgs = Type.getArgumentTypes(desc);\n                        Type nRet = Type.getReturnType(mapTo.desc);\n                        Type[] nArgs = Type.getArgumentTypes(mapTo.desc);\n                        if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {\n                            throw new RuntimeException(\"can't cast \" + nRet + \" to \" + orgRet);\n                        }\n\n                        if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {\n                            MtdInfo t = new MtdInfo();\n                            t.owner = \"L\" + owner + \";\";\n                            t.name = name;\n                            t.desc = desc;\n                            MtdInfo n = newMethodA(opcode, t, mapTo);\n                            super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc, isInterface);\n                        } else { // simple replace\n                            // checking for invalid replace\n                            if (isStatic) {\n                                if (!Arrays.deepEquals(orgArgs, nArgs)) {\n                                    throw new RuntimeException(\"arguments not equal: \" + owner + \".\" + name + desc\n                                            + \" <> \" + mapTo.owner + \".\" + mapTo.name + mapTo.desc);\n                                }\n                            } else {\n                                if (nArgs.length != orgArgs.length + 1) {","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/pxb1988/dex2jar/blob/b5bda4fb4935ae8b3869b422454ae3b3896c7bc1/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java#L417-L453","documentation":"Thrown by InvocationWeaver.visitMethodInsn while rewriting an INVOKE* instruction: if the original method returns a value (orgRet is not void) but the mapped replacement returns void (nRet is void), there is no value to leave on the stack for the consuming instruction, so the weaver refuses with 'can't cast <newRet> to <orgRet>'.","triggerScenarios":"A method mapping redirects a call to a replacement method that returns void while the original call site expects a return value (e.g. replacing 'String get()' with a void method), encountered during dex/jar weaving.","commonSituations":"Config mismatches after refactoring the target API — the replacement method signature was changed to return void, or the mapping's descriptor was hand-edited incorrectly.","solutions":["Update the mapping so the replacement method returns a type compatible with the original method's return type.","Point mapTo at an overload that still produces the value instead of a void variant.","If the value is truly unneeded, rewrite the original call sites too (or remove the consuming instructions) rather than mapping to a void method."],"exampleFix":"// before: mapping original 'Ljava/lang/String; get()' to '()V'\nmapTo = Lcom/X;->g()V\n// after\nmapTo = Lcom/X;->g()Ljava/lang/String;","handlingStrategy":"validation","validationCode":"// validate each mapping before weaving\nType orgRet = Type.getReturnType(original.desc);\nType nRet = Type.getReturnType(mapTo.desc);\nif (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {\n    throw new IllegalArgumentException(\"mapping drops return value: \" + original + \" -> \" + mapTo);\n}","typeGuard":null,"tryCatchPattern":"try {\n    new InvocationWeaver(cfg).weave();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"can't cast\")) {\n        throw new IllegalStateException(\"Mapping maps a value-returning method to a void method; fix mapTo\", e);\n    }\n    throw e;\n}","preventionTips":["Ensure replacements for value-returning methods also return a compatible value","Re-check mappings whenever the target library changes method signatures","Write a unit test that runs the weaver over the full mapping config before release"],"tags":["bytecode","weaving","signature-mismatch"],"backgroundTag":"incompatible-source-type","analyzedSha":"b5bda4fb4935ae8b3869b422454ae3b3896c7bc1","analyzedAt":"2026-09-08T00:44:01.258Z","contentChangedAt":"2026-09-08T00:44:01.258Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}