{"record":{"id":"06291d343ea9bb73","repo":"OpenFeign/feign","slug":"expected-a-class-parameterizedtype-or-genericarr","errorCode":null,"errorMessage":"Expected a Class, ParameterizedType, or GenericArrayType, but <{type}> is of type {className}","messagePattern":"Expected a Class, ParameterizedType, or GenericArrayType, but <(.+?)> is of type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/feign/Types.java","lineNumber":74,"sourceCode":"        throw new IllegalArgumentException();\n      }\n      return (Class<?>) rawType;\n\n    } else if (type instanceof GenericArrayType) {\n      Type componentType = ((GenericArrayType) type).getGenericComponentType();\n      return Array.newInstance(getRawType(componentType), 0).getClass();\n\n    } else if (type instanceof TypeVariable) {\n      // We could use the variable's bounds, but that won't work if there are multiple. Having a raw\n      // type that's more general than necessary is okay.\n      return Object.class;\n\n    } else if (type instanceof WildcardType) {\n      return getRawType(((WildcardType) type).getUpperBounds()[0]);\n\n    } else {\n      String className = type == null ? \"null\" : type.getClass().getName();\n      throw new IllegalArgumentException(\n          \"Expected a Class, ParameterizedType, or \"\n              + \"GenericArrayType, but <\"\n              + type\n              + \"> is of type \"\n              + className);\n    }\n  }\n\n  /** Returns true if {@code a} and {@code b} are equal. */\n  static boolean equals(Type a, Type b) {\n    if (a == b) {\n      return true; // Also handles (a == null && b == null).\n\n    } else if (a instanceof Class) {\n      return a.equals(b); // Class already specifies equals().\n\n    } else if (a instanceof ParameterizedType) {\n      if (!(b instanceof ParameterizedType)) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/core/src/main/java/feign/Types.java#L56-L92","documentation":"Types.getRawType() resolves the raw Class behind a java.lang.reflect Type but only understands Class, ParameterizedType, GenericArrayType and WildcardType. Any other Type implementation (or null) triggers this IllegalArgumentException naming the offending type and its class.","triggerScenarios":"Passing a TypeVariable, custom Type implementation, or null to Types.getRawType (directly or via encoders/contracts that use it), e.g. feeding a generic method's TypeVariable into encoder type resolution.","commonSituations":"Custom Encoder/Decoder implementations calling Types.getRawType on unbound type variables; proxy/reflection frameworks producing exotic Type implementations; version changes where types flow differently through the contract.","solutions":["Pass a Class, ParameterizedType, or GenericArrayType instead of a TypeVariable","Resolve type variables to concrete types first (e.g. via Types.resolve or getGenericSuperclass)","Null-check the Type before calling getRawType","If the type comes from a framework, capture the concrete body type at build time"],"exampleFix":"// before\nType t = method.getTypeParameters()[0]; // TypeVariable -> IllegalArgumentException\n// after\nType t = method.getGenericReturnType(); // ParameterizedType/Class\nClass<?> raw = Types.getRawType(t);","handlingStrategy":"type-guard","validationCode":"if (type == null || type instanceof TypeVariable) throw new IllegalArgumentException(\"Use a concrete Class/ParameterizedType, got: \" + type);","typeGuard":"static boolean isResolvable(Type t) { return t instanceof Class || t instanceof ParameterizedType || t instanceof GenericArrayType || t instanceof WildcardType; }","tryCatchPattern":"try { Class<?> raw = Types.getRawType(type); } catch (IllegalArgumentException e) { /* fall back to Types.resolve with declaring context */ }","preventionTips":["Never pass TypeVariables from generic methods directly","Resolve generics against the concrete subclass before calling","Null-check types from reflection APIs"],"tags":["reflection","types","generic-type","java","illegal-argument"],"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"}