{"record":{"id":"9368218db064f1b2","repo":"quarkusio/quarkus","slug":"a-message-bundle-method-must-return-java-lang-stri","errorCode":null,"errorMessage":"A message bundle method must return java.lang.String: %s#%s","messagePattern":"A message bundle method must return java\\.lang\\.String: (.+?)#(.+?)","errorType":"exception","errorClass":"MessageBundleException","httpStatus":null,"severity":"error","filePath":"extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java","lineNumber":1038,"sourceCode":"                cc.extends_(ClassDesc.of(defaultBundleImpl));\n            }\n            cc.defaultConstructor();\n\n            // key -> method\n            Map<String, MessageMethod> keyMap = new LinkedHashMap<>();\n            List<MethodInfo> methods = new ArrayList<>(bundleInterfaceWrapper.methods());\n            // Sort methods\n            methods.sort(Comparator.comparing(MethodInfo::name).thenComparing(Comparator.comparing(MethodInfo::toString)));\n\n            for (MethodInfo method : methods) {\n                cc.method(methodDescOf(method), mc -> {\n                    List<ParamVar> params = new ArrayList<>(method.parametersCount());\n                    for (int i = 0; i < method.parametersCount(); i++) {\n                        String paramName = method.parameterName(i);\n                        params.add(mc.parameter(paramName != null ? paramName : \"arg\" + i, i));\n                    }\n                    if (!method.returnType().name().equals(DotNames.STRING)) {\n                        throw new MessageBundleException(\n                                String.format(\"A message bundle method must return java.lang.String: %s#%s\",\n                                        bundleInterface, method.name()));\n                    }\n                    LOG.debugf(\"Found message bundle method %s on %s\", method, bundleInterface);\n\n                    AnnotationInstance messageAnnotation;\n                    if (defaultBundleInterface != null) {\n                        MethodInfo defaultBundleMethod = bundleInterfaceWrapper.method(method.name(),\n                                method.parameterTypes().toArray(new Type[] {}));\n                        if (defaultBundleMethod == null) {\n                            throw new MessageBundleException(\n                                    String.format(\"Default bundle method not found on %s: %s\", bundleInterface, method));\n                        }\n                        messageAnnotation = defaultBundleMethod.annotation(Names.MESSAGE);\n                    } else {\n                        messageAnnotation = method.annotation(Names.MESSAGE);\n                    }\n","sourceCodeStart":1020,"sourceCodeEnd":1056,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java#L1020-L1056","documentation":"Message bundle interface methods are generated to return localized text, so every method must declare java.lang.String as its return type. If a method returns anything else (int, StringBuilder, custom type, void), MessageBundleProcessor throws during build for that method.","triggerScenarios":"Declaring `StringBuilder hello(String name);` or `int count();` on a @MessageBundle interface; accidental generic/wrapper return types like `Object` or `Optional<String>`.","commonSituations":"Copying method signatures from a service class into the bundle interface; auto-completing the wrong overload; refactoring the return type for one purpose and forgetting templates need plain Strings.","solutions":["Change the method's return type to String: `String hello(String name);`","If structured data is needed, return String of the rendered message and parse in the caller, or move non-message logic out of the bundle interface.","Rebuild to confirm all bundle methods now return String."],"exampleFix":"// before\n@Message(\"Hello {name}\")\nStringBuilder hello(String name);\n\n// after\n@Message(\"Hello {name}\")\nString hello(String name);","handlingStrategy":"validation","validationCode":"// Every bundle method must return String\nfor (java.lang.reflect.Method m : AppMessages.class.getMethods()) {\n    if (m.getDeclaringClass() != AppMessages.class) continue;\n    if (m.getReturnType() != String.class) {\n        throw new IllegalStateException(\"Must return String: \" + m);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always declare String return types in bundle interfaces","Never copy service-class signatures into bundles","Enable IDE inspections for annotation-validated interfaces"],"tags":["quarkus","qute","message-bundle","type-safety"],"backgroundTag":"message-bundle-method-signature-invalid","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"}