{"record":{"id":"4ac53d25b9f26a94","repo":"quarkusio/quarkus","slug":"something-went-wrong-during-parameter-type-resolut","errorCode":null,"errorMessage":"Something went wrong during parameter type resolution - expected  to be a Continuation with a generic type","messagePattern":"Something went wrong during parameter type resolution - expected  to be a Continuation with a generic type","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/KotlinUtil.java","lineNumber":24,"sourceCode":"final class KotlinUtil {\n\n    private static final Type VOID_CLASS = Type.create(SchedulerDotNames.VOID, Type.Kind.CLASS);\n\n    private KotlinUtil() {\n    }\n\n    static boolean isSuspendMethod(MethodInfo methodInfo) {\n        if (!methodInfo.parameterTypes().isEmpty()) {\n            return methodInfo.parameterType(methodInfo.parametersCount() - 1).name()\n                    .equals(SchedulerDotNames.CONTINUATION);\n        }\n        return false;\n    }\n\n    static Type determineReturnTypeOfSuspendMethod(MethodInfo methodInfo) {\n        Type lastParamType = methodInfo.parameterType(methodInfo.parametersCount() - 1);\n        if (lastParamType.kind() != Type.Kind.PARAMETERIZED_TYPE) {\n            throw new IllegalStateException(\"Something went wrong during parameter type resolution - expected \"\n                    + lastParamType + \" to be a Continuation with a generic type\");\n        }\n        lastParamType = lastParamType.asParameterizedType().arguments().get(0);\n        if (lastParamType.kind() != Type.Kind.WILDCARD_TYPE) {\n            throw new IllegalStateException(\"Something went wrong during parameter type resolution - expected \"\n                    + lastParamType + \" to be a Continuation with a generic type\");\n        }\n        lastParamType = lastParamType.asWildcardType().superBound();\n        if (lastParamType.name().equals(SchedulerDotNames.KOTLIN_UNIT)) {\n            return VOID_CLASS;\n        }\n        return lastParamType;\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":39,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/KotlinUtil.java#L6-L39","documentation":"KotlinUtil.determineReturnTypeOfSuspendMethod inspects the synthetic Continuation parameter that the Kotlin compiler appends to suspend functions to extract the return type. If the last parameter is not a parameterized Continuation type, the method info is not a valid Kotlin suspend method and deployment fails with this IllegalStateException.","triggerScenarios":"A method detected as a Kotlin suspend @Scheduled method whose generated signature lacks a generic Continuation as the last parameter — typically when non-Kotlin (Java) methods are misrouted into suspend handling or bytecode/annotation tooling strips generics.","commonSituations":"Mixing Java and Kotlin scheduled methods with custom annotation processing; unusual Kotlin compiler versions producing different signatures; hand-written or transformed bytecode mimicking suspend methods.","solutions":["Ensure only genuine Kotlin suspend fun methods are routed through KotlinUtil (isSuspendMethod check first)","Rebuild with a standard, current Kotlin compiler version","Inspect the method's bytecode (javap -v) to confirm the Continuation parameter is parameterized","If using Java, declare the scheduled method normally (void return) instead of emulating suspend"],"exampleFix":"// before (Java method treated as suspend)\npublic void job(Continuation c) { ... }\n// after (plain Java scheduled method)\n@Scheduled(every = \"10s\")\npublic void job() { ... }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fun MethodInfo?.isValidSuspendMethod(): Boolean {\n    if (this == null || parametersCount() == 0) return false\n    val last = parameterType(parametersCount() - 1)\n    return last.kind() == org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE\n}","tryCatchPattern":"try { Type t = KotlinUtil.determineReturnTypeOfSuspendMethod(mi); }\ncatch (IllegalStateException e) { /* treat as non-suspend method */ }","preventionTips":["Only route Kotlin suspend fun through suspend-specific handling","Check isSuspendMethod before determining return type","Use a standard current Kotlin compiler","Verify bytecode signatures after adding bytecode transformers"],"tags":["kotlin","coroutines","scheduler","build-time","quarkus"],"backgroundTag":"invalid-kotlin-suspend-signature","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"}