{"record":{"id":"405ae1f41cc52294","repo":"quarkusio/quarkus","slug":"could-not-find-messagebodywriter-for-entityclass","errorCode":null,"errorMessage":"Could not find MessageBodyWriter for ${entityClass}","messagePattern":"Could not find MessageBodyWriter for (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java","lineNumber":146,"sourceCode":"        }\n        // FIXME: this should belong somewhere else as it's generic\n        @SuppressWarnings(\"unchecked\")\n        MessageBodyWriter<Object>[] writers = (MessageBodyWriter<Object>[]) serialisers\n                .findWriters(null, entityClass, mediaType)\n                .toArray(ServerSerialisers.NO_WRITER);\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        boolean wrote = false;\n        for (MessageBodyWriter<Object> writer : writers) {\n            if (writer.isWriteable(entityClass, entityType, context.getAllAnnotations(), mediaType)) {\n                // FIXME: spec doesn't really say what headers we should use here\n                writer.writeTo(entity, entityClass, entityType, context.getAllAnnotations(), mediaType,\n                        new QuarkusMultivaluedHashMap<>(), baos);\n                wrote = true;\n                break;\n            }\n        }\n        if (!wrote) {\n            throw new IllegalStateException(\"Could not find MessageBodyWriter for \" + entityClass);\n        }\n        // At this point we can only pray that the resulting output is a UTF-8 string\n        return baos.toString(StandardCharsets.UTF_8.name());\n    }\n\n    public static void setHeaders(ResteasyReactiveRequestContext context, ServerHttpResponse response) {\n        setHeaders(context, response, Collections.emptyList());\n    }\n\n    public static void setHeaders(ResteasyReactiveRequestContext context, ServerHttpResponse response,\n            List<PublisherResponseHandler.StreamingResponseCustomizer> customizers) {\n        if (!response.headWritten()) {\n            response.setStatusCode(Response.Status.OK.getStatusCode());\n            response.setResponseHeader(HttpHeaders.CONTENT_TYPE, MediaType.SERVER_SENT_EVENTS);\n            if (context.getTarget().getStreamElementType() != null) {\n                response.setResponseHeader(SSE_CONTENT_TYPE, context.getTarget().getStreamElementType().toString());\n            }\n            response.setChunked(true);","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java#L128-L164","documentation":"SseUtil.serialiseDataToString formats server-sent-event data by finding a MessageBodyWriter for the event's entity class and media type. If no registered writer can serialize the entity, it throws this IllegalStateException, so the SSE event cannot be written.","triggerScenarios":"Sending an object over an SSE endpoint (OutboundSseEvent.data(obj) / SseEventBuilder) whose class has no MessageBodyWriter for the negotiated media type (typically text/plain or the event's media type) — e.g. sending a POJO without a writer for text/plain.","commonSituations":"Emitting custom POJOs over SSE without registering a writer; relying on JSON writers while the SSE event media type defaults to text/plain; sending types unsupported by the installed extensions (e.g. missing RESTEasy Jackson/JSON-B dependency).","solutions":["Add the missing serialization extension (e.g. quarkus-rest-jackson or quarkus-rest-jsonb) so POJOs can be written.","Send a String or use .data(obj, MediaType.APPLICATION_JSON_TYPE) so a JSON writer applies to the event.","Register a custom MessageBodyWriter for the entity class and its media type.","Set the event's media type explicitly in the SseEventBuilder to match a writer you have available."],"exampleFix":"// before\neventBuilder.data(myPojo); // no writer for text/plain\n// after\neventBuilder.data(myPojo, MediaType.APPLICATION_JSON_TYPE); // with quarkus-rest-jackson on classpath","handlingStrategy":"validation","validationCode":"// before sending an SSE event, confirm a writer exists for the entity and media type\nif (jakarta.ws.rs.ext.RuntimeDelegate.getInstance() != null) {\n    // or check your provider registry: writers.containsKey(new MediaTypeKey(entityClass, mediaType))\n}\n// simplest guard: only send types known to have writers\nif (!(data instanceof String || data instanceof Number)) {\n    ensureJsonWriterRegistered(data.getClass());\n}","typeGuard":"static boolean hasKnownSseWriter(Object data) {\n    return data instanceof String || data instanceof Number || data instanceof Boolean\n        || jsonExtensionOnClasspath(); // quarkus-rest-jackson / quarkus-rest-jsonb\n}","tryCatchPattern":"try {\n    String s = SseUtil.serialiseDataToString(context, data, mediaType);\n    emitter.send(s);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Could not find MessageBodyWriter\")) {\n        log.error(\"Register a MessageBodyWriter for \" + data.getClass() + \" or send JSON with an explicit media type\");\n    }\n    throw e;\n}","preventionTips":["Add quarkus-rest-jackson or quarkus-rest-jsonb when sending POJOs over SSE.","Pass an explicit media type (e.g. APPLICATION_JSON_TYPE) to OutboundSseEvent data.","Prefer String payloads for SSE unless JSON serialization is configured.","Smoke-test SSE endpoints for every entity type they emit."],"tags":["quarkus","resteasy-reactive","sse","messagebodywriter","serialization"],"backgroundTag":"no-messagebodywriter","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"}