modelcontextprotocol/servers · error · Error

No response body

Error message

No response body

What it means

Thrown by `fetchSafely` when the fetch response has a null/absent body (`response.body` is falsy). This guards the streaming reader logic, which assumes a readable body exists. Common for responses that carry all data in headers or for certain error responses.

Source

Thrown at src/everything/tools/gzip-file-as-resource.ts:197

 */
async function fetchSafely(
  url: URL,
  { maxBytes, timeoutMillis }: { maxBytes: number; timeoutMillis: number }
): Promise<ArrayBuffer> {
  const controller = new AbortController();
  const timeout = setTimeout(
    () =>
      controller.abort(
        `Fetching ${url} took more than ${timeoutMillis} ms and was aborted.`
      ),
    timeoutMillis
  );

  try {
    // Fetch the data
    const response = await fetch(url, { signal: controller.signal });
    if (!response.body) {
      throw new Error("No response body");
    }

    // Note: we can't trust the Content-Length header: a malicious or clumsy server could return much more data than advertised.
    // We check it here for early bail-out, but we still need to monitor actual bytes read below.
    const contentLengthHeader = response.headers.get("content-length");
    if (contentLengthHeader != null) {
      const contentLength = parseInt(contentLengthHeader, 10);
      if (contentLength > maxBytes) {
        throw new Error(
          `Content-Length for ${url} exceeds max of ${maxBytes}: ${contentLength}`
        );
      }
    }

    // Read the fetched data from the response body
    const reader = response.body.getReader();
    const chunks = [];
    let totalSize = 0;

View on GitHub (pinned to 76d64c822f)

Solutions

  1. Point the `data` argument at a URL that returns an actual body (200 with content).
  2. Verify the URL in a browser/curl: `curl -i <url>` and confirm a non-empty body.
  3. If the endpoint legitimately returns no content for some inputs, choose a URL/path that returns the file.

Example fix

# before
URL returns 'HTTP/1.1 204 No Content'
# after
use a URL that returns the actual file bytes (200 OK with body)
Defensive patterns

Strategy: validation

Validate before calling

// pre-check with a lightweight HEAD/GET that you control
async function hasBody(url: string): Promise<boolean> {
  const r = await fetch(url, { method: 'GET' });
  return r.body != null;
}

Try / catch

try {
  await callGzipTool({ data: url });
} catch (e) {
  if (e instanceof Error && e.message === 'No response body') {
    // pick a URL that returns a body
  }
}

Prevention

When it happens

Trigger: The remote server returns a response with no body (e.g. a 204 No Content, a HEAD-style response, or a server error that omits the body), or the runtime/transport yields `response.body === null`.

Common situations: Pointing the gzip tool at a URL that returns 204, a misconfigured endpoint, an authenticated redirect that lands on a no-content response, or a server that streams via a mechanism the fetch impl doesn't expose as a ReadableStream.

Related errors


AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12). Data as JSON: /api/errors/f4b5b94cbf5e74eb. Report an issue: GitHub.