tinyhumansai/openhuman · error · anyhow::Error

No SSE data frame found in MCP response: {body}

Error message

No SSE data frame found in MCP response: {body}

What it means

parse_sse_message found SSE events in the response body but none carried a data frame. Used as the whole-body fallback when a stream ends without a data frame, so the body is included for diagnosis — typically a server that answered plain JSON over an SSE accept header, or an empty keep-alive stream.

Source

Thrown at src/openhuman/mcp/http_client/client_helpers.rs:12

use super::{McpAuthChallenge, McpRemoteTool, McpSseEvent};
use anyhow::Context;
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use serde_json::Value;
use std::collections::HashMap;

pub(super) fn parse_sse_message(body: &str) -> anyhow::Result<Value> {
    let events = parse_sse_events(body)?;
    let event = events
        .into_iter()
        .find_map(|event| event.data)
        .ok_or_else(|| anyhow::anyhow!("No SSE data frame found in MCP response: {body}"))?;
    Ok(event)
}

/// Return the first JSON `data:` frame from the **fully-terminated** prefix of a
/// partially-received SSE buffer, or `None` if no complete event carrying a data
/// frame has arrived yet.
///
/// MCP Streamable HTTP lets a server keep the POST response's SSE stream open
/// after it has already emitted the single JSON-RPC reply, so reading the whole
/// body to stream-close (`response.text().await`) stalls every tool call until
/// the server closes or the request times out — the dominant transport cause of
/// the multi-minute skill latency in #4195. Reading incrementally and stopping
/// at the first data frame lets the call return the instant the reply lands.
///
/// Only the portion up to the last blank-line event boundary is parsed, so a
/// half-received final `data:` line is never decoded as truncated JSON.
/// Keepalive comments and dataless events are skipped (returns `None`, keep
/// reading). An SSE event terminates on a blank line; `\r\n` is normalised to

View on GitHub (pinned to 7491200858)

Solutions

  1. Check the logged body: if it is plain JSON, the server ignored the SSE accept header and should be contacted without SSE
  2. Verify Content-Type of the response matches text/event-stream
  3. Retry — brief streams may close before the first frame flushes
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at src/openhuman/mcp/http_client/client_helpers.rs:12 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/005d9f70b40cd20f. Report an issue: GitHub.