{"record":{"id":"3bc8c8035d7e0363","repo":"OpenFeign/feign","slug":"not-an-iterator-type-rawtype","errorCode":null,"errorMessage":"Not an iterator type ${rawType}","messagePattern":"Not an iterator type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java","lineNumber":101,"sourceCode":"      }\n      reader.reset();\n      return new JacksonIterator<Object>(\n          actualIteratorTypeArgument(type), mapper, response, reader);\n    } catch (RuntimeJsonMappingException e) {\n      if (e.getCause() != null && e.getCause() instanceof IOException) {\n        throw IOException.class.cast(e.getCause());\n      }\n      throw e;\n    }\n  }\n\n  private static Type actualIteratorTypeArgument(Type type) {\n    if (!(type instanceof ParameterizedType)) {\n      throw new IllegalArgumentException(\"Not supported type \" + type.toString());\n    }\n    ParameterizedType parameterizedType = (ParameterizedType) type;\n    if (!Iterator.class.equals(parameterizedType.getRawType())) {\n      throw new IllegalArgumentException(\n          \"Not an iterator type \" + parameterizedType.getRawType().toString());\n    }\n    return ((ParameterizedType) type).getActualTypeArguments()[0];\n  }\n\n  public static JacksonIteratorDecoder create() {\n    return create(Collections.<Module>emptyList());\n  }\n\n  public static JacksonIteratorDecoder create(Iterable<Module> modules) {\n    return new JacksonIteratorDecoder(\n        new ObjectMapper()\n            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)\n            .registerModules(modules));\n  }\n\n  public static JacksonIteratorDecoder create(ObjectMapper objectMapper) {\n    return new JacksonIteratorDecoder(objectMapper);","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java#L83-L119","documentation":"Companion check in actualIteratorTypeArgument: the type is parameterized but its raw type is not java.util.Iterator, so the decoder cannot stream it and throws IllegalArgumentException 'Not an iterator type X'.","triggerScenarios":"Using JacksonIteratorDecoder with a method returning List<User>, Collection<User>, or any other ParameterizedType that is not Iterator<T>.","commonSituations":"Applying the iterator decoder globally to all methods (e.g. in Feign.builder().decoder(JacksonIteratorDecoder.create())) while most methods return List<T>; migrating methods without switching back to the standard decoder.","solutions":["Return Iterator<T> from methods handled by JacksonIteratorDecoder.","Register a composed decoder: new JacksonDecoder() for normal types and JacksonIteratorDecoder for Iterator<T> methods (or use the auto-detecting setup).","Only set JacksonIteratorDecoder per-method/per-client where streaming is intended.","Check the declared return type's generic raw type."],"exampleFix":"// before\n.decoder(new JacksonIteratorDecoder()) // used with List<User> return types\n// after\n.decoder(new Decoder.Default(new JacksonDecoder(), new JacksonIteratorDecoder()));\n// and declare streaming methods as Iterator<User>","handlingStrategy":"type-guard","validationCode":"static boolean isIteratorType(Type type) {\n  return type instanceof ParameterizedType\n      && java.util.Iterator.class.equals(((ParameterizedType) type).getRawType());\n}","typeGuard":"static boolean suitableForIteratorDecoder(java.lang.reflect.Method m) {\n  Type t = m.getGenericReturnType();\n  return t instanceof ParameterizedType && java.util.Iterator.class.equals(((ParameterizedType) t).getRawType());\n}","tryCatchPattern":"try {\n  return feignClient.call();\n} catch (feign.codec.DecodeException e) {\n  if (e.getCause() instanceof IllegalArgumentException && e.getCause().getMessage().startsWith(\"Not an iterator type\")) {\n    throw new IllegalStateException(\"Use the standard JacksonDecoder for non-Iterator return types\", e);\n  }\n  throw e;\n}","preventionTips":["Use a composed Decoder that routes List<T> to JacksonDecoder and Iterator<T> to JacksonIteratorDecoder","Do not set JacksonIteratorDecoder as the only decoder for multi-shaped APIs","Grep Feign interfaces for return types before enabling streaming decoding"],"tags":["jackson","iterator","decoder","generics"],"backgroundTag":"type-mismatch","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"}