conductor-oss/conductor · error · RuntimeException

No data found in SSE response

Error message

No data found in SSE response: {sseBody}

What it means

Thrown by parseSseResponse when an SSE response body contains zero usable `data:` lines. It iterates lines, keeps data: payloads, skips empty and [DONE] markers, and if nothing remained it cannot produce JSON. Means the server sent an SSE stream with only comments, event: lines, ping/keep-alive, or was empty.

Solutions

  1. Log the raw SSE body (it is in the exception message) to see what frames were actually sent.
  2. Confirm the server emits `data:` lines for JSON-RPC responses per the MCP SSE transport spec.
  3. If the server uses a different event field, use a compliant server or a custom SSE parser.
  4. Check the connection wasn't closed/truncated before the result event arrived.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    mcpService.listTools(serverUrl, headers);
} catch (RuntimeException e) {
    if (e.getMessage().contains("No data found in SSE response")) {
        // server sent an SSE stream with no data: lines; check transport compatibility
    }
    throw e;
}

Prevention

When it happens

Trigger: Server's content-type was text/event-stream but the body was an empty stream, only `event:` headers, only `: comment` lines, or only `[DONE]` markers; the actual JSON-RPC result event was never delivered (server closed the stream early).

Common situations: Long-lived SSE endpoint where the response event hadn't arrived yet but the connection closed; server uses a non-standard field instead of `data:`; interceptor stripped data lines; the response was a heartbeat-only stream.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/3a9de34bb83b77aa. Report an issue: GitHub.

Appendix: source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/mcp/MCPService.java:365

        log.debug("Parsing SSE response: {}", sseBody);

        // Find all "data:" lines and concatenate their content
        StringBuilder jsonData = new StringBuilder();
        String[] lines = sseBody.split("\n");

        for (String line : lines) {
            String trimmed = line.trim();
            if (trimmed.startsWith("data:")) {
                String data = trimmed.substring(5).trim();
                // Skip empty data or "[DONE]" markers
                if (!data.isEmpty() && !data.equals("[DONE]")) {
                    jsonData.append(data);
                }
            }
        }

        if (jsonData.length() == 0) {
            throw new RuntimeException("No data found in SSE response: " + sseBody);
        }

        try {
            return objectMapper.readTree(jsonData.toString());
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse SSE data as JSON: " + jsonData, e);
        }
    }

    /** Executes one MCP request and follows redirects while protecting sensitive headers. */
    private ResponsePayload execute(Request initialRequest) throws Exception {
        Request request = initialRequest;
        for (int redirects = 0; redirects <= 5; redirects++) {
            try (Response response = httpClient.newCall(request).execute()) {
                if (!response.isRedirect()) {
                    return new ResponsePayload(
                            response.code(),
                            response.header("Content-Type", "application/json"),

View on GitHub (pinned to cf7c3e4a8a)