{"record":{"id":"ded57d2722d1b478","repo":"quarkusio/quarkus","slug":"cannot-directly-return-collections-or-arrays-using","errorCode":null,"errorMessage":"Cannot directly return collections or arrays using JAXB. You need to wrap it into a root element class. Problematic method is '{entry.getActualClassInfo().name}.{methodInfo.name}'","messagePattern":"Cannot directly return collections or arrays using JAXB\\. You need to wrap it into a root element class\\. Problematic method is '(.+?)\\.(.+?)'","errorType":"exception","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-jaxb/deployment/src/main/java/io/quarkus/resteasy/reactive/jaxb/deployment/ResteasyReactiveJaxbProcessor.java","lineNumber":97,"sourceCode":"    }\n\n    @BuildStep\n    void registerClassesToBeBound(ResteasyReactiveResourceMethodEntriesBuildItem resourceMethodEntries,\n            JaxRsResourceIndexBuildItem index,\n            BuildProducer<JaxbClassesToBeBoundBuildItem> classesToBeBoundBuildItemBuildProducer) {\n        Set<ClassInfo> classesInfo = new HashSet<>();\n\n        IndexView indexView = index.getIndexView();\n        for (ResteasyReactiveResourceMethodEntriesBuildItem.Entry entry : resourceMethodEntries.getEntries()) {\n            ResourceMethod resourceInfo = entry.getResourceMethod();\n            MethodInfo methodInfo = entry.getMethodInfo();\n            ClassInfo effectiveReturnType = getEffectiveClassInfo(methodInfo.returnType(), indexView);\n\n            if (effectiveReturnType != null) {\n                // When using \"application/xml\", the return type needs to be registered\n                if (producesXml(resourceInfo)) {\n                    if (!isTypeCompatibleWithJaxb(methodInfo.returnType())) {\n                        throw new DeploymentException(\n                                \"Cannot directly return collections or arrays using JAXB. You need to wrap it \"\n                                        + \"into a root element class. Problematic method is '\"\n                                        + entry.getActualClassInfo().name() + \".\" + methodInfo.name() + \"'\");\n                    }\n\n                    classesInfo.add(effectiveReturnType);\n                }\n\n                // When using \"multipart/form-data\", the parts that use \"application/xml\" need to be registered\n                if (producesMultipart(resourceInfo)) {\n                    classesInfo.addAll(getEffectivePartsUsingXml(effectiveReturnType, indexView));\n                }\n            }\n\n            // If consumes \"application/xml\" or \"multipart/form-data\", we register all the classes of the parameters\n            boolean consumesXml = consumesXml(resourceInfo);\n            boolean consumesMultipart = consumesMultipart(resourceInfo);\n            if (consumesXml || consumesMultipart) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-jaxb/deployment/src/main/java/io/quarkus/resteasy/reactive/jaxb/deployment/ResteasyReactiveJaxbProcessor.java#L79-L115","documentation":"When producing XML (application/xml) via JAXB, a JAX-RS resource method cannot directly return a Collection or array — JAXB requires a root element class to marshal. During deployment, RESTEasy Reactive's JAXB processor scans resource methods whose @Produces includes an XML media type, and if the effective return type is not JAXB-compatible (collection/array without a JAXB root), the build fails with this DeploymentException pointing at the offending method.","triggerScenarios":"A resource method annotated (explicitly or by negotiation) with @Produces(MediaType.APPLICATION_XML) (or application/*+xml) returns List<T>, Set<T>, T[], Response wrapping such, or any type failing the JAXB root-element compatibility check.","commonSituations":"Returning List<MyEntity> from an endpoint that defaults to XML because the client sends Accept: application/xml; switching @Produces from JSON to XML without restructuring the return type; copying JSON endpoints to XML endpoints.","solutions":["Wrap the collection in a JAXB root element class (e.g. a @XmlRootElement wrapper holding a List<T> with @XmlElement wrapping)","Change the endpoint to @Produces(MediaType.APPLICATION_JSON) if XML output is not actually needed","Narrow the method's @Produces so it does not advertise XML if the return type cannot be marshalled","Return a single @XmlRootElement entity instead of a collection, or stream via a custom MessageBodyWriter"],"exampleFix":"// before\n@GET\n@Produces(MediaType.APPLICATION_XML)\npublic List<User> users() { ... }\n\n// after\n@XmlRootElement(name = \"users\")\nclass Users {\n    @XmlElement(name = \"user\")\n    public List<User> users;\n}\n\n@GET\n@Produces(MediaType.APPLICATION_XML)\npublic Users users() { ... }","handlingStrategy":"type-guard","validationCode":"static boolean isXmlCompatible(Class<?> rt) {\n    if (Collection.class.isAssignableFrom(rt) || rt.isArray()) return false;\n    return rt.isAnnotationPresent(jakarta.xml.bind.annotation.XmlRootElement.class);\n}\n// before declaring @Produces(APPLICATION_XML) on a method, assert:\nif (!isXmlCompatible(method.getReturnType())) throw new IllegalStateException(\"Wrap the return type in a JAXB root element\");","typeGuard":"static boolean hasJaxbRoot(Class<?> c) {\n    return c.isAnnotationPresent(jakarta.xml.bind.annotation.XmlRootElement.class);\n}","tryCatchPattern":"try {\n    deploy();\n} catch (DeploymentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Cannot directly return collections or arrays using JAXB\")) {\n        // wrap the return type named in the message\n    }\n}","preventionTips":["Never return raw collections/arrays from @Produces(APPLICATION_XML) endpoints","Use @XmlRootElement wrapper classes for XML list responses","Match @Produces to what the return type can actually marshal","Decide JSON vs XML per endpoint early in the design"],"tags":["jaxb","quarkus","xml","resteasy-reactive"],"backgroundTag":"jaxb-root-element-required","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"}