{"record":{"id":"0124b634f5ff6ae5","repo":"quarkusio/quarkus","slug":"a-background-function-cannot-return-a-value","errorCode":null,"errorMessage":"A background function cannot return a value","messagePattern":"A background function cannot return a value","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java","lineNumber":100,"sourceCode":"\n    /**\n     * Handle RawBackgroundFunction\n     *\n     * @param event\n     * @param context\n     */\n    public static void handle(String event, Context context) {\n        //TODO allow to access the context from the function somehow.\n        try {\n            Object input = null;\n            if (invoker.hasInput()) {\n                input = reader.readValue(event);\n            }\n            FunqyServerResponse response = dispatch(input);\n\n            Object value = response.getOutput().await().indefinitely();\n            if (value != null) {\n                throw new RuntimeException(\"A background function cannot return a value\");\n            }\n        } catch (JacksonException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    /**\n     * Handle CloudEventsFunction\n     *\n     * @param cloudEvent\n     */\n    public static void handle(CloudEvent cloudEvent) {\n        FunqyServerResponse response = dispatch(cloudEvent);\n\n        Object value = response.getOutput().await().indefinitely();\n        if (value != null) {\n            throw new RuntimeException(\"A background function cannot return a value\");\n        }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/funqy/funqy-google-cloud-functions/runtime/src/main/java/io/quarkus/funqy/gcp/functions/FunqyCloudFunctionsBindingRecorder.java#L82-L118","documentation":"Google Cloud background functions (e.g. Pub/Sub, Firestore triggers) must return void. When a Funqy function bound to a background Cloud Function invocation produces a non-null output, FunqyCloudFunctionsBindingRecorder throws this RuntimeException after dispatching, because a background function has no response channel to deliver a value to.","triggerScenarios":"A Funqy function with a non-void return type is invoked via the background-function entry point handle(Object event): the function completes successfully, but response.getOutput().await().indefinitely() yields a non-null value.","commonSituations":"Developers define a Funqy @Function that returns a payload (e.g. a DTO) for request/response use, then deploy it as a GCP background/cloud-event function; or they reuse one function for both HTTP and background invocations.","solutions":["Change the background function's return type to void (or String/Uni that resolves to null) so no output is produced.","If output is needed, bind the function to an HTTP-invoked Cloud Function instead of a background one.","Wrap the value-producing logic in a function returning Uni<Void> or a CompletableFuture that completes with null.","Exclude the function from background export via quarkus.funqy.export and register a separate void function."],"exampleFix":"// before\npublic class MyFunctions {\n    @Function\n    public String process(Event in) { return \"done\"; }\n}\n// after\npublic class MyFunctions {\n    @Function\n    public void process(Event in) { /* side effects only */ }\n}","handlingStrategy":"validation","validationCode":"if (!java.lang.reflect.Modifier.class.getClass().equals(void.class)) { /* inspect method return type */ }\n// At build/config time: assert the @Function method's return type is void before deploying as background\nMethod m = MyFunctions.class.getMethod(\"process\", Event.class);\nif (m.getReturnType() != void.class) throw new IllegalStateException(\"Background function must be void\");","typeGuard":"boolean isBackgroundSafe(Method m) { return m.getReturnType() == void.class || Uni.class.equals(m.getReturnType()); }","tryCatchPattern":"try { dispatch(input); } catch (RuntimeException e) { if (e.getMessage().contains(\"background function cannot return\")) { log.error(\"Fix function signature: return void\", e); } throw e; }","preventionTips":["Declare background functions with void return types","Use Uni<Void> when async handling is needed","Keep request/response and background logic in separate functions","Test with the GCP background-function entry point before deploying"],"tags":["gcp","background-function","funqy","return-type"],"backgroundTag":"background-function-return-value","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}