{"record":{"id":"81b4abf62af68661","repo":"quarkusio/quarkus","slug":"uni-must-be-used-with-type-parameter-e-g-uni-str","errorCode":null,"errorMessage":"Uni must be used with type parameter (e.g. Uni<String>).","messagePattern":"Uni must be used with type parameter \\(e\\.g\\. Uni<String>\\)\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionInvoker.java","lineNumber":57,"sourceCode":"                }\n                parameterInjectors.add(injector);\n            }\n        }\n        constructor = new FunctionConstructor(targetClass);\n        Class<?> returnType = method.getReturnType();\n        if (returnType != null) {\n            if (Uni.class.isAssignableFrom(returnType)) {\n                outputType = null;\n                isAsync = true;\n                Type genericReturnType = method.getGenericReturnType();\n                if (genericReturnType instanceof ParameterizedType) {\n                    Type[] actualParams = ((ParameterizedType) genericReturnType).getActualTypeArguments();\n                    if (actualParams.length == 1) {\n                        outputType = actualParams[0];\n                    }\n                }\n                if (outputType == null) {\n                    throw new IllegalArgumentException(\n                            \"Uni must be used with type parameter (e.g. Uni<String>).\");\n                }\n            } else {\n                outputType = method.getGenericReturnType();\n            }\n        }\n    }\n\n    /**\n     * Allow storage of binding specific objects that are specific to the function.\n     * i.e. json marshallers\n     *\n     * @return\n     */\n    public Map<String, Object> getBindingContext() {\n        return bindingContext;\n    }\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/funqy/funqy-server-common/runtime/src/main/java/io/quarkus/funqy/runtime/FunctionInvoker.java#L39-L75","documentation":"Funqy supports reactive functions returning Mutiny Uni. The FunctionInvoker constructor inspects the generic return type to determine the output type. A raw Uni (no type parameter, e.g. method returns plain Uni) gives no output type, so an IllegalArgumentException is thrown at startup.","triggerScenarios":"Declaring @Funq public Uni noTypeParam() { ... } — returning Uni without a generic parameter such as Uni<String>.","commonSituations":"Writing a reactive function quickly and forgetting the generic; IDEs generating raw Uni when refactoring from CompletionStage; type erasure surprises when returning Uni.fromFuture(...).","solutions":["Add an explicit type parameter to the Uni return type","If the value is dynamic, use Uni<Object> or a concrete domain type","Rebuild; the check runs when the invoker is constructed at startup"],"exampleFix":"// before\n@Funq public Uni getData() { ... }\n// after\n@Funq public Uni<String> getData() { ... }","handlingStrategy":"type-guard","validationCode":"// Verify Uni return types are parameterized before startup\nstatic void assertParameterizedUni(Method m) {\n    Type rt = m.getGenericReturnType();\n    if (rt instanceof Class && Uni.class.isAssignableFrom((Class<?>) rt))\n        throw new IllegalArgumentException(m + \" must return Uni<T> with a type parameter\");\n}","typeGuard":"static boolean isParameterizedUni(Type returnType) {\n    return returnType instanceof ParameterizedType\n        && ((ParameterizedType) returnType).getRawType() == Uni.class;\n}","tryCatchPattern":"try {\n    registry.register(...);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Uni must be used with type parameter\"))\n        log.errorf(\"Fix return type to Uni<T>, method: %s\", e.getMessage());\n    throw e;\n}","preventionTips":["Never return raw Uni in @Funq methods","Let the compiler infer generics instead of casting to raw Uni","Add a reflection-based startup test asserting all @Funq returns are parameterized","Prefer concrete domain types over Uni<Object>"],"tags":["quarkus","funqy","mutiny","generics"],"backgroundTag":"raw-generics-not-allowed","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"}