{"record":{"id":"362aafe1b1060b65","repo":"quarkusio/quarkus","slug":"when-using-cloudevent-generic-parameter-must-be","errorCode":null,"errorMessage":"When using CloudEvent<> generic parameter must be used.","messagePattern":"When using CloudEvent<> generic parameter must be used\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/funqy/funqy-knative-events/runtime/src/main/java/io/quarkus/funqy/runtime/bindings/knative/events/KnativeEventsBindingRecorder.java","lineNumber":124,"sourceCode":"                    throw new IllegalStateException(\"Function for trigger '\" + trigger + \"' has multiple matching invokers\");\n                }\n\n                v.add(invoker);\n                return v;\n            });\n\n            if (invoker.hasInput()) {\n                Type inputType = invoker.getInputType();\n\n                if (CloudEvent.class.equals(Reflections.getRawType(inputType))) {\n                    if (inputType instanceof ParameterizedType) {\n                        Type[] params = ((ParameterizedType) inputType).getActualTypeArguments();\n                        if (params.length == 1) {\n                            inputType = params[0];\n                            invoker.getBindingContext().put(INPUT_CE_DATA_TYPE, inputType);\n                        }\n                    } else {\n                        throw new RuntimeException(\"When using CloudEvent<> generic parameter must be used.\");\n                    }\n                }\n\n                validateNotBoxedByteArray(inputType, invoker.getName(), \"input\");\n\n                JavaType javaInputType = objectMapper.constructType(inputType);\n                ObjectReader reader = objectMapper.readerFor(javaInputType);\n                invoker.getBindingContext().put(DATA_OBJECT_READER, reader);\n                QueryReader queryReader = queryMapper.readerFor(inputType);\n                invoker.getBindingContext().put(QueryReader.class.getName(), queryReader);\n            }\n            if (invoker.hasOutput()) {\n                Type outputType = invoker.getOutputType();\n\n                if (CloudEvent.class.equals(Reflections.getRawType(outputType))) {\n                    if (outputType instanceof ParameterizedType) {\n                        Type[] params = ((ParameterizedType) outputType).getActualTypeArguments();\n                        if (params.length == 1) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/funqy/funqy-knative-events/runtime/src/main/java/io/quarkus/funqy/runtime/bindings/knative/events/KnativeEventsBindingRecorder.java#L106-L142","documentation":"When a Funqy Knative function's input type is a raw CloudEvent without a generic parameter, the binding cannot determine the CE data type and throws this RuntimeException. CloudEvent must be parameterized (e.g. CloudEvent<MyPojo>) so the payload type is captured in the binding context.","triggerScenarios":"A function is declared with input CloudEvent (raw type) or CloudEvent with zero type arguments while init inspects the generic parameterization; the else branch throws because getActualTypeArguments() is empty/invalid.","commonSituations":"Developers write CloudEvent to 'keep it generic' or after an IDE strips imports/type args; code migrated from plain Funqy without adding the generic parameter.","solutions":["Parameterize the input: change CloudEvent to CloudEvent<YourPayloadType>.","If the payload is unstructured, use CloudEvent<String> or CloudEvent<byte[]>.","Ensure the generic argument is not itself a raw type or wildcard that loses the actual class.","Keep the declared type parameter concrete so init can put INPUT_CE_DATA_TYPE into the binding context."],"exampleFix":"// before\npublic void handle(CloudEvent event) { ... }\n// after\npublic void handle(CloudEvent<MyPojo> event) { ... }","handlingStrategy":"type-guard","validationCode":"Type t = method.getGenericParameterTypes()[0];\nif (t instanceof ParameterizedType pt && pt.getRawType() == CloudEvent.class\n    && pt.getActualTypeArguments().length == 1\n    && !(pt.getActualTypeArguments()[0] instanceof WildcardType)) {\n    // ok: concrete CloudEvent<T>\n}","typeGuard":"boolean isConcreteCloudEvent(Type t) {\n    return t instanceof ParameterizedType pt\n        && pt.getRawType() == CloudEvent.class\n        && pt.getActualTypeArguments().length == 1\n        && !(pt.getActualTypeArguments()[0] instanceof WildcardType);\n}","tryCatchPattern":"try { registry.init(...); } catch (RuntimeException e) { if (e.getMessage().contains(\"CloudEvent<> generic parameter must be used\")) { log.error(\"Parameterize CloudEvent input, e.g. CloudEvent<Pojo>\", e); } throw e; }","preventionTips":["Always write CloudEvent<T> with a concrete T","Enable -Xlint:rawtypes and treat raw-type warnings as errors","Add an ArchUnit/unit test rejecting raw CloudEvent parameters","Avoid wildcards in function signatures"],"tags":["knative","cloudevent","generics","funqy","type-parameter"],"backgroundTag":"raw-generic-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"}