tursodatabase/turso · error · DatabaseError

No response body

Error message

No response body

What it means

The fetch to /v3/cursor returned an OK (2xx) status but response.body was null or undefined, so no stream reader could be created. The cursor protocol is a streaming NDJSON body, so an OK response without a body cannot be consumed at all. This is a transport/runtime anomaly, not a SQL or auth problem (those surface as HTTP errors earlier).

Solutions

  1. Reproduce with curl -i -X POST <url>/v3/cursor ... and confirm the server actually streams a body
  2. If this happens in tests, fix the fetch stub to include a ReadableStream body (e.g. Response with a stream of NDJSON lines)
  3. Update @tursodatabase/serverless to the latest patch release in case of runtime compatibility fixes
  4. Report to Turso if the raw HTTP exchange shows 200-with-empty-body from the server itself

Example fix

// before (test mock without a body)
globalThis.fetch = async () => new Response('', { status: 200 });

// after
const body = new ReadableStream({
  start(c) {
    c.enqueue(new TextEncoder().encode('{"baton":null,"base_url":null}\n'));
    c.close();
  },
});
globalThis.fetch = async () => new Response(body, { status: 200 });
Defensive patterns

Strategy: try-catch

Type guard

import { DatabaseError } from '@tursodatabase/serverless';

function isNoBody(e: unknown): e is DatabaseError {
  return e instanceof DatabaseError && e.message === 'No response body';
}

Try / catch

try {
  return await session.execute(sql, args);
} catch (e) {
  if (isNoBody(e)) throw new Error('server returned 200 with no body — check fetch polyfill/proxy');
  throw e;
}

Prevention

When it happens

Trigger: A fetch polyfill or test mock that returns a Response without a ReadableStream body; a server or intermediary replying 200 with an genuinely empty body; unusual edge runtimes whose fetch returns a null body for certain response shapes.

Common situations: Unit tests that stub globalThis.fetch with `new Response()` or a plain object lacking body; a misbehaving gateway between the client and the database; upgrading the runtime (Node/workerd version) changes fetch body behavior.

Related errors


AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20). Data as JSON: /api/errors/ad0bcd5094d4a298. Report an issue: GitHub.

Appendix: source

Thrown at serverless/javascript/src/protocol.ts:322

  }

  if (!response.ok) {
    let errorMessage = `HTTP error! status: ${response.status}`;
    try {
      const errorBody = await response.text();
      const errorData = JSON.parse(errorBody);
      if (errorData.message) {
        errorMessage = errorData.message;
      }
    } catch {
      // If we can't parse the error body, use the default HTTP error message
    }
    throw new DatabaseError(errorMessage);
  }

  const reader = response.body?.getReader();
  if (!reader) {
    throw new DatabaseError('No response body');
  }

  const decoder = new TextDecoder();
  let buffer = '';
  let cursorResponse: CursorResponse | undefined;

  // First, read until we get the cursor response (first line)
  try {
    while (!cursorResponse) {
      const { done, value } = await reader.read();
      if (done) break;

      buffer += decoder.decode(value, { stream: true });

      const newlineIndex = buffer.indexOf('\n');
      if (newlineIndex !== -1) {
        const line = buffer.slice(0, newlineIndex).trim();
        buffer = buffer.slice(newlineIndex + 1);

View on GitHub (pinned to c1e5928725)