{"record":{"id":"b6ccf23433818340","repo":"OpenFeign/feign","slug":"streams-are-not-supported-when-using-reactive-wrap","errorCode":null,"errorMessage":"Streams are not supported when using Reactive Wrappers","messagePattern":"Streams are not supported when using Reactive Wrappers","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"reactive/src/main/java/feign/reactive/ReactiveDelegatingContract.java","lineNumber":58,"sourceCode":"      final Type type = metadata.returnType();\n      if (!isReactive(type)) {\n        throw new IllegalArgumentException(\n            String.format(\n                \"Method %s of contract %s doesn't returns a org.reactivestreams.Publisher\",\n                metadata.configKey(), targetType.getSimpleName()));\n      }\n\n      /*\n       * we will need to change the return type of the method to match the return type contained\n       * within the Publisher\n       */\n      Type[] actualTypes = ((ParameterizedType) type).getActualTypeArguments();\n      if (actualTypes.length > 1) {\n        throw new IllegalStateException(\"Expected only one contained type.\");\n      } else {\n        Class<?> actual = Types.getRawType(actualTypes[0]);\n        if (Stream.class.isAssignableFrom(actual)) {\n          throw new IllegalArgumentException(\n              \"Streams are not supported when using Reactive Wrappers\");\n        }\n        metadata.returnType(type);\n      }\n    }\n\n    return methodsMetadata;\n  }\n\n  /**\n   * Ensure that the type provided implements a Reactive Streams Publisher.\n   *\n   * @param type to inspect.\n   * @return true if the type implements the Reactive Streams Publisher specification.\n   */\n  private boolean isReactive(Type type) {\n    if (!ParameterizedType.class.isAssignableFrom(type.getClass())) {\n      return false;","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/reactive/src/main/java/feign/reactive/ReactiveDelegatingContract.java#L40-L76","documentation":"If the type contained in the Publisher is (or extends) java.util.stream.Stream, the contract rejects it with IllegalArgumentException. Streams are one-shot, non-replayable lazy sequences and cannot be reliably materialized across reactive publishers/decoders, so the reactive module forbids them as element types.","triggerScenarios":"Declaring a method that returns Publisher<Stream<T>> (e.g. Flux<Stream<T>> or Mono<Stream<T>>) in a Feign interface used with ReactiveDelegatingContract.","commonSituations":"Mapping decoding code from streaming HTTP clients to reactive ones; interfaces where an entity already exposes a stream API; confusion between streaming decoding (unsupported here) and reactive publishers.","solutions":["Change the contained element type to a concrete collection or entity, e.g. Flux<List<T>> or Flux<T> instead of Flux<Stream<T>>","Collect the stream into a List before returning, or model the data as a POJO","If you need true streaming, use a different Feign module (e.g. the streaming/async decoding support of a specific client) instead of the reactive wrapper"],"exampleFix":"// before\nFlux<Stream<User>> users();\n// after\nFlux<User> users();\n","handlingStrategy":"validation","validationCode":"// reject Stream inside Publisher return types before building the target\nif (Flux.class.isAssignableFrom(raw)) {\n  Class<?> inner = Types.getRawType(((ParameterizedType) type).getActualTypeArguments()[0]);\n  if (java.util.stream.Stream.class.isAssignableFrom(inner))\n    throw new IllegalStateException(\"Do not use Stream inside reactive return types\");\n}","typeGuard":"static boolean isStreamInside(Type publisherType) {\n  return publisherType instanceof ParameterizedType\n      && java.util.stream.Stream.class.isAssignableFrom(\n          feign.Types.getRawType(((ParameterizedType) publisherType).getActualTypeArguments()[0]));\n}","tryCatchPattern":null,"preventionTips":["Model element types as POJOs or collections, never java.util.stream.Stream","Don't confuse reactive streaming (backpressure) with java.util.stream.Stream"],"tags":["reactive","stream","unsupported-type"],"backgroundTag":"unsupported-enum-value","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}