danielmiessler/Fabric · error · Error

No response from fabric backend

Error message

No response from fabric backend

What it means

Thrown by the /chat endpoint when fabricResponse.ok is true but fabricResponse.body is null/undefined. For a streaming SSE response the body should always be a ReadableStream; a null body with a 200 means the request was made without streaming (e.g. a GET/HEAD-style empty response), the runtime does not expose streaming bodies, or a redirect/204-style response slipped through. It effectively means the proxy cannot pipe Fabric's output to the client.

Source

Thrown at web/src/routes/chat/+server.ts:116

    });

    console.log('6. Fabric response:', {
      status: fabricResponse.status,
      ok: fabricResponse.ok,
      statusText: fabricResponse.statusText
    });

    if (!fabricResponse.ok) {
      console.error('Error from Fabric API:', {
        status: fabricResponse.status,
        statusText: fabricResponse.statusText
      });
      throw new Error(`Fabric API error: ${fabricResponse.statusText}`);
    }

    const stream = fabricResponse.body;
    if (!stream) {
      throw new Error('No response from fabric backend');
    }

    // Create a TransformStream to inspect the data without modifying it
    const transformStream = new TransformStream({
      transform(chunk, controller) {
        const text = new TextDecoder().decode(chunk);
        if (text.startsWith('data: ')) {
          try {
            const data = JSON.parse(text.slice(6));
            console.log('Stream chunk format:', {
              type: data.type,
              format: data.format,
              contentLength: data.content?.length
            });
          } catch (e) {
            console.log('Failed to parse stream chunk:', text);
          }
        }

View on GitHub (pinned to 338b89cfe9)

Solutions

  1. Check the logged Fabric response object — if status is 200 but body is null, replay the same request with curl against the Fabric port to see whether it actually streams
  2. Ensure the proxied request preserves the streaming method/headers (Accept: text/event-stream) that Fabric requires
  3. Verify the SvelteKit adapter supports streaming responses (node adapter does; some serverless previews do not)
  4. Upgrade/hot-restart the Fabric server if it is returning empty 200s; check its logs for mid-stream aborts

Example fix

// before
const stream = fabricResponse.body;
if (!stream) {
  throw new Error('No response from fabric backend');
}

// after
const stream = fabricResponse.body;
if (!stream) {
  // Distinguish 'backend returned nothing' from 'streaming unsupported here'
  const text = await fabricResponse.text().catch(() => '');
  throw error(502, text
    ? `Fabric backend returned a non-streaming response: ${text.slice(0, 200)}`
    : 'No response body from fabric backend');
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Confirm streaming is supported in this runtime before proxying
if (typeof ReadableStream === 'undefined' || !('body' in Response.prototype)) {
  throw error(500, 'Streaming responses unsupported by this adapter');
}

Type guard

function hasBody(r: Response): r is Response & { body: ReadableStream<Uint8Array> } {
  return r.ok && r.body instanceof ReadableStream;
}

// usage
if (!hasBody(fabricResponse)) {
  const text = await fabricResponse.text().catch(() => '');
  throw error(502, text || 'No response from fabric backend');
}

Try / catch

try {
  if (!hasBody(fabricResponse)) throw error(502, 'No response from fabric backend');
  return new Response(fabricResponse.body.pipeThrough(transformStream), {
    headers: { 'Content-Type': 'text/event-stream' }
  });
} catch (e) {
  console.error('Fabric streaming failed:', e);
  throw error(502, 'Fabric stream unavailable');
}

Prevention

When it happens

Trigger: Fabric backend returning 200 with an empty body (pattern produced no output), a fetch that followed a redirect to a non-streaming response, running under a runtime/adapter where response.body is not implemented, or the request to Fabric missing the streaming headers Fabric expects so it returns an empty 200.

Common situations: SvelteKit adapter or preview environment without full streaming support, Fabric version that closed the stream before writing anything, middleware (compression/proxy) that consumed or stripped the body before the handler read it.

Related errors


AI-assisted analysis of danielmiessler/Fabric@338b89cfe9 (2026-08-15). Data as JSON: /api/errors/0bc6947dd6f7e988. Report an issue: GitHub.