pxb1988/dex2jar · error · RuntimeException
can't cast to
Error message
can't cast to
What it means
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>'.
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.
Example fix
// before: mapping original 'Ljava/lang/String; get()' to '()V' mapTo = Lcom/X;->g()V // after mapTo = Lcom/X;->g()Ljava/lang/String;
Defensive patterns
Strategy: validation
Validate before calling
// validate each mapping before weaving
Type orgRet = Type.getReturnType(original.desc);
Type nRet = Type.getReturnType(mapTo.desc);
if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
throw new IllegalArgumentException("mapping drops return value: " + original + " -> " + mapTo);
} Try / catch
try {
new InvocationWeaver(cfg).weave();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("can't cast")) {
throw new IllegalStateException("Mapping maps a value-returning method to a void method; fix mapTo", e);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- invalid ret type:
- arguments not equal:
- while accept code in method
- zero-width instruction op=0x%02x
- jump out of insns -> %04x
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/65770af2fbbf6255.
Report an issue: GitHub.
Appendix: source
Thrown at dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java:435
return mv==null?null: new ReplaceMethodVisitor(mv);
}
class ReplaceMethodVisitor extends MethodVisitor {
public ReplaceMethodVisitor(MethodVisitor mv) {
super(ASM9, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc,
boolean isInterface) {
MtdInfo mapTo = findTargetMethod("L" + owner + ";", name, desc);
if (mapTo != null) {
boolean isStatic = opcode == INVOKESTATIC;
Type orgRet = Type.getReturnType(desc);
Type[] orgArgs = Type.getArgumentTypes(desc);
Type nRet = Type.getReturnType(mapTo.desc);
Type[] nArgs = Type.getArgumentTypes(mapTo.desc);
if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
throw new RuntimeException("can't cast " + nRet + " to " + orgRet);
}
if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {
MtdInfo t = new MtdInfo();
t.owner = "L" + owner + ";";
t.name = name;
t.desc = desc;
MtdInfo n = newMethodA(opcode, t, mapTo);
super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc, isInterface);
} else { // simple replace
// checking for invalid replace
if (isStatic) {
if (!Arrays.deepEquals(orgArgs, nArgs)) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc
+ " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
} else {
if (nArgs.length != orgArgs.length + 1) {View on GitHub (pinned to b5bda4fb49)