{"record":{"id":"fac467dd6605fec0","repo":"quarkusio/quarkus","slug":"bug-don-t-know-how-to-generate-jvm-bridge-method-fac467","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/PanacheRepositoryClassOperationGenerationVisitor.java","lineNumber":221,"sourceCode":"        // get a bounds-erased descriptor\n        String descriptor = method.descriptor();\n        // make sure we need a bridge\n        if (!userMethods.contains(method.name() + \"/\" + descriptor)) {\n            MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE,\n                    method.name(),\n                    descriptor,\n                    null,\n                    null);\n            List<org.jboss.jandex.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                org.jboss.jandex.Type paramType = parameters.get(i);\n                if (paramType.kind() == org.jboss.jandex.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(Opcodes.ALOAD, i + 1);\n                if (paramType.kind() == org.jboss.jandex.Type.Kind.TYPE_VARIABLE) {\n                    String typeParamName = paramType.asTypeVariable().identifier();\n                    Type type = typeArguments.get(typeParamName).type();\n                    if (type.getSort() > Type.DOUBLE) {\n                        mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());\n                    } else {\n                        unboxIfRequired(mv, type);\n                    }\n                }\n            }\n\n            String targetDescriptor = method.descriptor(argMapper);\n            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,\n                    daoBinaryName,\n                    method.name(),\n                    targetDescriptor, false);","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheRepositoryClassOperationGenerationVisitor.java#L203-L239","documentation":"The repository Panache bytecode generator builds JVM bridge methods for generic methods. A bridge must load each parameter to forward it; primitives cannot be loaded as object references with ALOAD, so encountering Type.Kind.PRIMITIVE aborts generation with this IllegalStateException. It signals an unhandled case in the enhancement, not user misuse per se.","triggerScenarios":"visitEnd -> generateJvmBridge generates a bridge for a repository method whose parameters include a primitive (int, long, boolean, double, etc.), typically because a user method overrides a generic base method with a primitive-parameter signature.","commonSituations":"Kotlin/Java Panache repository implementing/overriding a generic PanacheRepositoryBase method with primitive parameters; a method whose erasure forces bridging (same name and erased signature as a type-variable method in the base class).","solutions":["Box the primitive parameter (use Integer/Long/Boolean or Kotlin nullable types) so the bridge can ALOAD it.","Rename the method to avoid the forced bridge against the generic supertype method.","Patch generateJvmBridge to compute the correct primitive load opcode instead of throwing, and contribute upstream to Quarkus."],"exampleFix":"// before\nfun persist(f: Boolean) { ... } // collides with generic base method, needs bridge\n// after\nfun persist(flag: Boolean?) { ... } // boxed parameter, bridge generatable","handlingStrategy":"type-guard","validationCode":"boolean bridgeable(org.jboss.jandex.Type[] parameters) {\n    for (org.jboss.jandex.Type p : parameters)\n        if (p.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE) return false;\n    return true;\n}","typeGuard":"boolean hasPrimitiveParams(List<org.jboss.jandex.Type> params) {\n    return params.stream().anyMatch(p -> p.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE);\n}","tryCatchPattern":"try {\n    generateJvmBridge(method, parameters);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"primitive parameters\")) {\n        // box parameters or skip bridge\n    } else throw e;\n}","preventionTips":["Don't override generic PanacheRepositoryBase methods with primitive parameters","Box primitives in repository method signatures","Report reproducible cases upstream to fix opcode handling"],"tags":["panache","bytecode","asm","bridge-method","repository"],"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-14T00:17:10.932Z"}