tinyhumansai/openhuman · warning · anyhow::Error
MCP notification {method} failed with {} — {}
Error message
MCP notification {method} failed with {} — {} What it means
A fire-and-forget JSON-RPC notification (e.g. `notifications/initialized`) POSTed to the MCP endpoint returned a non-2xx status; the message includes the method, status and response body. Notifications carry no id and expect no reply, so any non-success HTTP status is reported this way by `send_notification`.
Source
Thrown at src/openhuman/mcp/http_client/client.rs:477
}
async fn send_notification(&self, method: &str, params: Value) -> anyhow::Result<()> {
let body = json!({
"jsonrpc": "2.0",
"method": method,
"params": params,
});
let request = self
.http
.post(&self.endpoint)
.header(CONTENT_TYPE, "application/json")
.header(ACCEPT, MCP_HTTP_ACCEPT);
let request = self.apply_standard_headers(request, false, method, None, &[]);
let response = request.body(serde_json::to_vec(&body)?).send().await?;
let status = response.status();
if !status.is_success() {
let text = response.text().await.unwrap_or_default();
anyhow::bail!(
"MCP notification {method} failed with {} — {}",
status,
text
);
}
Ok(())
}
async fn send_jsonrpc(
&self,
method: &str,
params: Value,
options: RequestOptions,
) -> anyhow::Result<ResponseEnvelope> {
self.send_jsonrpc_inner(method, params, options, true).await
}
async fn send_jsonrpc_inner(View on GitHub (pinned to 7491200858)
Solutions
- If 401, refresh OAuth and re-initialize the session before retrying.
- If 404/unknown session, re-run the full initialize handshake (new `Mcp-Session-Id`).
- Verify the endpoint URL and any proxy settings; then retry once — notifications are idempotent.
- If the failure is transient (5xx), back off and retry.
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = client.send_notification(method, params).await {
let msg = e.to_string();
if msg.contains(" 401") || msg.contains(" 404") {
client.reset_session();
client.initialize().await?; // then re-send once
} else {
tracing::warn!("mcp notification {method} failed: {e}");
}
} Prevention
- Send notifications as part of the same session lifecycle as initialize — never after long idle gaps.
- Refresh OAuth tokens proactively before expiry windows.
- Treat notification failure as non-fatal unless the handshake depends on it.
When it happens
Trigger: Sending `notifications/initialized` or `notifications/cancelled` when the session id is stale (404), the OAuth token expired (401), or the endpoint is behind a gateway returning 4xx/5xx; servers that reject notifications for unknown sessions.
Common situations: Token expiring between `initialize` and the follow-up notification; server restarting and losing session state mid-handshake; misconfigured base URL pointing at a non-MCP route.
Related errors
- MCP HTTP {} — {}
- MCP error: {err}
- [transport:local] HTTP ${response.status}: ${text || respons
- stdio MCP server closed stdout while waiting for `{method}`
- MCP stdio error: {err}
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/ad4c46c63fdf476d.
Report an issue: GitHub.