{"record":{"id":"8b929eb6c06ebf9b","repo":"quarkusio/quarkus","slug":"unsupported-type-type","errorCode":null,"errorMessage":"Unsupported type: \" + type","messagePattern":"Unsupported type: \" \\+ type","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/redis-cache/deployment/src/main/java/io/quarkus/cache/redis/deployment/RedisCacheProcessor.java","lineNumber":219,"sourceCode":"        return result;\n    }\n\n    private static String typeToString(Type type) {\n        StringBuilder result = new StringBuilder();\n        typeToString(type, result);\n        return result.toString();\n    }\n\n    private static void typeToString(Type type, StringBuilder result) {\n        switch (type.kind()) {\n            case VOID, PRIMITIVE, CLASS -> result.append(type.name().toString());\n            case ARRAY -> {\n                typeToString(type.asArrayType().elementType(), result);\n                result.append(\"[]\".repeat(type.asArrayType().deepDimensions()));\n            }\n            case PARAMETERIZED_TYPE -> {\n                if (type.asParameterizedType().owner() != null) {\n                    throw new IllegalArgumentException(\"Unsupported type: \" + type);\n                }\n\n                result.append(type.name().toString());\n                result.append('<');\n                boolean first = true;\n                for (Type typeArgument : type.asParameterizedType().arguments()) {\n                    if (!first) {\n                        result.append(\", \");\n                    }\n                    typeToString(typeArgument, result);\n                    first = false;\n                }\n                result.append('>');\n            }\n            case WILDCARD_TYPE -> {\n                result.append('?');\n                if (type.asWildcardType().superBound() != null) {\n                    result.append(\" super \");","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/redis-cache/deployment/src/main/java/io/quarkus/cache/redis/deployment/RedisCacheProcessor.java#L201-L237","documentation":"The Redis cache deployment processor's typeToString converts Jandex Types into type strings for value-type configuration. Parameterized types with an owner type (e.g. Outer.Inner<...> where Inner is a nested class of Outer) are not supported by this converter, so it throws IllegalArgumentException.","triggerScenarios":"A cached method (or configured value-type) whose type is a member/nested parameterized class with a non-null owner, e.g. java.util.Map.Entry-style nested generic classes, reaches typeToString during deployment.","commonSituations":"Caching methods that return nested generic inner classes like Container.Payload<Thing>; using such a type as a type argument in List<Outer.Inner<X>>; newer Quarkus versions that started applying type conversion to previously ignored types.","solutions":["Refactor the cached type to a top-level class instead of a nested/inner parameterized class","Cache a simpler type (e.g. a record or wrapper at top level) and map to the nested type outside the cache","File/upgrade: check the Quarkus version for fixes to redis-cache type handling and upgrade","Configure value-type with the raw class form if generics are not essential for marshalling"],"exampleFix":"// before\nclass Container {\n  static class Payload<T> { T data; }\n}\n@CacheResult(cacheName=\"c\") Container.Payload<Item> load();\n// after\nclass Payload<T> { T data; }  // top-level class\n@CacheResult(cacheName=\"c\") Payload<Item> load();","handlingStrategy":"validation","validationCode":"if (valueClass.isMemberClass() || valueClass.getEnclosingClass() != null) {\n    throw new IllegalArgumentException(\"Move \" + valueClass + \" to a top-level class for Redis caching\");\n}","typeGuard":"static boolean isTopLevel(Class<?> c) { return c.getEnclosingClass() == null; }","tryCatchPattern":null,"preventionTips":["Keep cached value types top-level and non-generic-owner","Review return types of @CacheResult methods for nested generics","Test the application build after refactoring cached types"],"tags":["quarkus","redis-cache","jandex","generics","deployment"],"backgroundTag":"unsupported-type","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}