OpenFeign/feign · error · IllegalArgumentException

Method can't have continuation argument, only kotlin method…

Error message

Method %s can't have continuation argument, only kotlin method is allowed

What it means

KotlinMethodInfo.createInstance() validates that a method detected as a Kotlin suspend function actually has a resolvable Kotlin return type. If MethodKt.isSuspend(method) is true but getKotlinMethodReturnType returns null, it throws IllegalArgumentException stating the method can't have a continuation argument unless it is a proper Kotlin method.

Solutions

  1. Ensure the interface is authored in Kotlin and compiled with the same/m compatible Kotlin version as feign-kotlin
  2. Remove the Continuation parameter from Java-declared methods; declare them as suspend fun in Kotlin instead
  3. Verify the jar containing the interface was not obfuscated/processed in a way that strips @Metadata annotations
  4. Check the generated configKey in the message to identify the offending method and fix its declaration

Example fix

// before (Java interface)
Response getData(Continuation<? super Response> cont);
// after (Kotlin interface)
interface Api { suspend fun getData(): Response }
Defensive patterns

Strategy: validation

Validate before calling

// before building the target
Method m = Api.class.getMethod("getData");
if (MethodKt.isSuspend(m) && MethodKt.getKotlinMethodReturnType(m) == null) {
  throw new IllegalStateException("Method " + m + " must be declared as suspend fun in Kotlin");
}

Try / catch

try { Feign.builder().target(Api.class, url); }
catch (IllegalArgumentException e) {
  if (e.getMessage().contains("continuation argument")) throw new IllegalStateException("Declare the method as suspend fun in Kotlin", e);
  throw e;
}

Prevention

When it happens

Trigger: Registering a Feign target interface whose method is a suspend function compiled without Kotlin metadata, or a method whose last parameter is a Continuation but which is not a genuine suspend function (e.g. hand-written or processed by bytecode tools that strip metadata).

Common situations: Mixing Kotlin and Java modules where the interface was recompiled/obfuscated; using the feign-kotlin module with an interface written in Java that takes a kotlin.coroutines.Continuation parameter; Kotlin version mismatches altering metadata the reflection helpers rely on.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/0469751f76e4fa89. Report an issue: GitHub.

Appendix: source

Thrown at kotlin/src/main/java/feign/kotlin/KotlinMethodInfo.java:42

import java.util.concurrent.CompletableFuture;

class KotlinMethodInfo extends MethodInfo {

  KotlinMethodInfo(Type underlyingReturnType, boolean asyncReturnType) {
    super(underlyingReturnType, asyncReturnType);
  }

  static KotlinMethodInfo createInstance(Class<?> targetType, Method method) {
    final Type type = Types.resolve(targetType, targetType, method.getGenericReturnType());

    Type underlyingReturnType;
    boolean asyncReturnType;
    if (MethodKt.isSuspend(method)) {
      asyncReturnType = true;
      underlyingReturnType = MethodKt.getKotlinMethodReturnType(method);
      if (underlyingReturnType == null) {
        String configKey = Feign.configKey(targetType, method);
        throw new IllegalArgumentException(
            String.format(
                "Method %s can't have continuation argument, only kotlin method is allowed",
                configKey));
      }
    } else if (type instanceof ParameterizedType
        && Types.getRawType(type).isAssignableFrom(CompletableFuture.class)) {
      asyncReturnType = true;
      underlyingReturnType = ((ParameterizedType) type).getActualTypeArguments()[0];
    } else {
      asyncReturnType = false;
      underlyingReturnType = type;
    }

    return new KotlinMethodInfo(underlyingReturnType, asyncReturnType);
  }
}

View on GitHub (pinned to e2a1e27560)