quarkusio/quarkus · error · IllegalStateException

Something went wrong during parameter type resolution - expe

Error message

Something went wrong during parameter type resolution - expected  to be a Continuation with a generic type

What it means

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.

Source

Thrown at extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/KotlinUtil.java:24

final class KotlinUtil {

    private static final Type VOID_CLASS = Type.create(SchedulerDotNames.VOID, Type.Kind.CLASS);

    private KotlinUtil() {
    }

    static boolean isSuspendMethod(MethodInfo methodInfo) {
        if (!methodInfo.parameterTypes().isEmpty()) {
            return methodInfo.parameterType(methodInfo.parametersCount() - 1).name()
                    .equals(SchedulerDotNames.CONTINUATION);
        }
        return false;
    }

    static Type determineReturnTypeOfSuspendMethod(MethodInfo methodInfo) {
        Type lastParamType = methodInfo.parameterType(methodInfo.parametersCount() - 1);
        if (lastParamType.kind() != Type.Kind.PARAMETERIZED_TYPE) {
            throw new IllegalStateException("Something went wrong during parameter type resolution - expected "
                    + lastParamType + " to be a Continuation with a generic type");
        }
        lastParamType = lastParamType.asParameterizedType().arguments().get(0);
        if (lastParamType.kind() != Type.Kind.WILDCARD_TYPE) {
            throw new IllegalStateException("Something went wrong during parameter type resolution - expected "
                    + lastParamType + " to be a Continuation with a generic type");
        }
        lastParamType = lastParamType.asWildcardType().superBound();
        if (lastParamType.name().equals(SchedulerDotNames.KOTLIN_UNIT)) {
            return VOID_CLASS;
        }
        return lastParamType;
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure only genuine Kotlin suspend fun methods are routed through KotlinUtil (isSuspendMethod check first)
  2. Rebuild with a standard, current Kotlin compiler version
  3. Inspect the method's bytecode (javap -v) to confirm the Continuation parameter is parameterized
  4. If using Java, declare the scheduled method normally (void return) instead of emulating suspend

Example fix

// before (Java method treated as suspend)
public void job(Continuation c) { ... }
// after (plain Java scheduled method)
@Scheduled(every = "10s")
public void job() { ... }
Defensive patterns

Strategy: type-guard

Type guard

fun MethodInfo?.isValidSuspendMethod(): Boolean {
    if (this == null || parametersCount() == 0) return false
    val last = parameterType(parametersCount() - 1)
    return last.kind() == org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE
}

Try / catch

try { Type t = KotlinUtil.determineReturnTypeOfSuspendMethod(mi); }
catch (IllegalStateException e) { /* treat as non-suspend method */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4ac53d25b9f26a94. Report an issue: GitHub.