{"record":{"id":"00e59ec0a3d1b453","repo":"quarkusio/quarkus","slug":"bug-don-t-know-how-to-generate-jvm-bridge-method","errorCode":null,"errorMessage":"BUG: Don't know how to generate JVM bridge method for : has primitive parameters","messagePattern":"BUG: Don't know how to generate JVM bridge method for : has primitive parameters","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/KotlinPanacheClassOperationGenerationVisitor.java","lineNumber":357,"sourceCode":"        }\n    }\n\n    private void generateBridge(MethodInfo method, String descriptor) {\n        MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE,\n                method.name(),\n                descriptor,\n                null,\n                null);\n        List<Type> parameters = method.parameterTypes();\n        AsmUtil.copyParameterNames(mv, method);\n        mv.visitCode();\n        // this\n        mv.visitIntInsn(Opcodes.ALOAD, 0);\n        // each param\n        for (int i = 0; i < parameters.size(); i++) {\n            Type paramType = parameters.get(i);\n            if (paramType.kind() == Type.Kind.PRIMITIVE)\n                throw new IllegalStateException(\"BUG: Don't know how to generate JVM bridge method for \" + method\n                        + \": has primitive parameters\");\n            mv.visitIntInsn(getLoadOpcode(paramType), i + 1);\n            if (paramType.kind() == Type.Kind.TYPE_VARIABLE) {\n                String typeParamName = paramType.asTypeVariable().identifier();\n                org.objectweb.asm.Type type = getType(typeArguments.get(typeParamName).descriptor());\n                if (type.getSort() > org.objectweb.asm.Type.DOUBLE) {\n                    mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());\n                } else {\n                    unboxIfRequired(mv, type);\n                }\n            }\n        }\n\n        String targetDescriptor = method.descriptor(name -> typeArguments.get(name).get());\n        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,\n                classInfo.name().toString().replace('.', '/'),\n                method.name(),\n                targetDescriptor, false);","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/KotlinPanacheClassOperationGenerationVisitor.java#L339-L375","documentation":"The Kotlin Panache bytecode generator creates JVM bridge methods that forward calls to the erased generic method. Bridging a parameter requires loading a reference (ALOAD); primitive parameters (int, long, boolean...) cannot be loaded as references, so the generator aborts with this IllegalStateException, indicating an unsupported/unhandled case in the transformation.","triggerScenarios":"visitEnd -> generateBridge encounters a method whose parameters include a primitive Type.Kind.PRIMITIVE while generating bridge methods for a Kotlin Panache class with generic (type-variable) methods.","commonSituations":"Declaring a Kotlin Panache repository/entity method with primitive parameters that collides with a generic base-class method (same name/erasure), forcing a bridge; Kotlin methods like fun findByName(name: String, active: Boolean) overloading generic Panache methods.","solutions":["Change the method parameter from a primitive type to its boxed wrapper (Int -> Integer/Int?, boolean -> Boolean) so a reference load is possible.","Rename the method so it no longer requires a JVM bridge against the generic supertype method.","Report/fix in Quarkus: add primitive load-opcode handling (IRETURN/LLOAD etc.) to generateBridge in KotlinPanacheClassOperationGenerationVisitor."],"exampleFix":"// before (Kotlin)\noverride fun findById(id: Long): Person? = ...  // triggers bridge over primitive\n// after\noverride fun findById(id: Long?): Person? = ...  // boxed Long? avoids primitive bridge","handlingStrategy":"type-guard","validationCode":"fun bridgeable(method: MethodInfo): Boolean =\n    method.parameters().none { it.type().kind() == Type.Kind.PRIMITIVE }","typeGuard":"fun hasPrimitiveParams(parameters: List<Type>): Boolean =\n    parameters.any { it.kind() == Type.Kind.PRIMITIVE }","tryCatchPattern":"try {\n    visitor.generateBridge(method, parameters);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"primitive parameters\")) {\n        // skip or box parameters and retry\n    } else throw e;\n}","preventionTips":["Avoid overriding generic Panache base methods with primitive-parameter signatures","Use boxed/nullable types in Kotlin overrides of Panache methods","Keep Quarkus updated for bridge-generation fixes"],"tags":["panache","kotlin","bytecode","asm","bridge-method"],"backgroundTag":"primitive-bridge-method-unsupported","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}