apache/superset · error

Response body is not available for streaming

Error message

Response body is not available for streaming

What it means

Thrown by the streaming export hook when response.ok is true but response.body is null. The hook iterates response.body.getReader() to stream chunks and compute progress; a null body makes streaming impossible. null bodies occur when fetch is intercepted (some service workers, opaque no-cors responses) or in environments without ReadableStream support.

Source

Thrown at superset-frontend/src/components/StreamingExportModal/useStreamingExport.ts:241

          payload,
          filename,
          exportType,
          exportSource,
          expectedRows,
          abortControllerRef.current.signal,
        );
        // Guard: ensure URL has app root prefix for subdirectory deployments
        const prefixedUrl = ensureUrlPrefix(url);
        const response = await fetch(prefixedUrl, fetchOptions);

        if (!response.ok) {
          throw new Error(
            `Export failed: ${response.status} ${response.statusText}`,
          );
        }

        if (!response.body) {
          throw new Error('Response body is not available for streaming');
        }

        const contentDisposition = response.headers.get('Content-Disposition');
        const defaultFilename = `export.${exportType}`;
        let serverFilename = defaultFilename;

        if (contentDisposition) {
          const filenameMatch =
            contentDisposition.match(/filename="?([^"]+)"?/);
          if (filenameMatch && filenameMatch[1]) {
            serverFilename = filenameMatch[1];
          }
        }

        const reader = response.body.getReader();
        const chunks: Uint8Array[] = [];
        let receivedLength = 0;
        let rowsProcessed = 0;

View on GitHub (pinned to f4587218dd)

Solutions

  1. Bypass/whitelist the Superset export routes in any service worker so the native streamed response passes through.
  2. Verify browser support for ReadableStream and that no fetch polyfill strips body.
  3. If interception is unavoidable, make the interceptor construct the Response with a real stream (e.g. new Response(stream)).
  4. In fetch mocks/tests, provide body: new ReadableStream(...).

Example fix

// before (interceptor)
return new Response(await cached.text()); // body may be null

// after (interceptor)
return new Response(new ReadableStream({ start(c) { c.enqueue(bytes); c.close(); } }));
Defensive patterns

Strategy: type-guard

Validate before calling

const response = await fetch(url, opts);
if (!response.body) {
  // fall back to blob download instead of streaming
  const blob = await response.blob();
  saveAs(blob, filename);
}

Type guard

const isStreamableResponse = (r: Response): boolean => r.body instanceof ReadableStream || typeof r.body?.getReader === 'function';

Try / catch

try { streamExport(response); } catch (e) { if (e.message === 'Response body is not available for streaming') downloadViaBlob(response); else throw e; }

Prevention

When it happens

Trigger: An export fetch whose response exposes no ReadableStream: a service worker returning a synthetic Response (new Response(blob)) without a stream, a no-cors/opaque response, or an old browser/polyfill lacking response.body.

Common situations: PWA/service-worker wrappers around Superset synthesizing responses; corporate proxies that fully buffer and re-serve responses; outdated browser baselines; test environments using fetch mocks that forget to set body.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/5298a7ed0c20835a. Report an issue: GitHub.