vercel/ai · error

The response body is empty.

Error message

The response body is empty.

What it means

After a successful (ok) HTTP response, StructuredObject streams the body. If `response.body` is null the library cannot stream and throws this error. It guards against servers that return 200 with no body.

Source

Thrown at packages/angular/src/lib/structured-object.ng.ts:167

      const response = await actualFetch(this.options.api, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...normalizeHeaders(this.options.headers),
        },
        credentials: this.options.credentials,
        signal: abortController.signal,
        body: JSON.stringify(input),
      });

      if (!response.ok) {
        throw new Error(
          (await response.text()) ?? 'Failed to fetch the response.',
        );
      }

      if (response.body == null) {
        throw new Error('The response body is empty.');
      }

      let accumulatedText = '';
      let latestObject: DeepPartial<RESULT> | undefined = undefined;

      await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
        new WritableStream<string>({
          write: async chunk => {
            if (abortController?.signal.aborted) {
              throw new DOMException('Stream aborted', 'AbortError');
            }
            accumulatedText += chunk;

            const { value } = await parsePartialJson(accumulatedText);
            const currentObject = value as DeepPartial<RESULT>;

            if (!isDeepEqualData(latestObject, currentObject)) {
              latestObject = currentObject;

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Ensure the server endpoint actually streams the partial-JSON text response with a body.
  2. Check the endpoint path/configuration — a wrong route may return an empty 200.
  3. Test in a modern browser/runtime that supports `response.body` streaming (TextDecoderStream support too).

Example fix

// server: stream a body instead of returning empty 200
// before
res.statusCode = 200; res.end();
// after
res.statusCode = 200;
res.write(JSON.stringify(partialObject)); res.end();
Defensive patterns

Strategy: validation

Validate before calling

const res = await fetch(api, { method: 'GET' });
if (!res.ok) throw new Error(`bad status ${res.status}`);
const hasBody = res.body != null;
if (!hasBody) throw new Error('Endpoint returned no stream body');

Type guard

function hasStreamBody(r: Response): r is Response & { body: ReadableStream } { return r.body != null; }

Try / catch

try {
  /* structured object flow */
} catch (e) {
  if (e instanceof Error && e.message === 'The response body is empty.') {
    // server returned ok with no body; fix endpoint
  }
  throw e;
}

Prevention

When it happens

Trigger: The fetch response is `ok` but `response.body == null` — typically a 204/no-content response or an environment (older browser/polyfill) where streaming response bodies are unsupported.

Common situations: Hitting an endpoint that returns an empty success response instead of a text stream; testing in a runtime without ReadableStream response bodies; misconfigured server route returning no content.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/895d54de14307835. Report an issue: GitHub.