{"record":{"id":"ad0bcd5094d4a298","repo":"tursodatabase/turso","slug":"no-response-body","errorCode":null,"errorMessage":"No response body","messagePattern":"No response body","errorType":"exception","errorClass":"DatabaseError","httpStatus":null,"severity":"error","filePath":"serverless/javascript/src/protocol.ts","lineNumber":322,"sourceCode":"  }\n\n  if (!response.ok) {\n    let errorMessage = `HTTP error! status: ${response.status}`;\n    try {\n      const errorBody = await response.text();\n      const errorData = JSON.parse(errorBody);\n      if (errorData.message) {\n        errorMessage = errorData.message;\n      }\n    } catch {\n      // If we can't parse the error body, use the default HTTP error message\n    }\n    throw new DatabaseError(errorMessage);\n  }\n\n  const reader = response.body?.getReader();\n  if (!reader) {\n    throw new DatabaseError('No response body');\n  }\n\n  const decoder = new TextDecoder();\n  let buffer = '';\n  let cursorResponse: CursorResponse | undefined;\n\n  // First, read until we get the cursor response (first line)\n  try {\n    while (!cursorResponse) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      buffer += decoder.decode(value, { stream: true });\n\n      const newlineIndex = buffer.indexOf('\\n');\n      if (newlineIndex !== -1) {\n        const line = buffer.slice(0, newlineIndex).trim();\n        buffer = buffer.slice(newlineIndex + 1);","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/serverless/javascript/src/protocol.ts#L304-L340","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reproduce with curl -i -X POST <url>/v3/cursor ... and confirm the server actually streams a body","If this happens in tests, fix the fetch stub to include a ReadableStream body (e.g. Response with a stream of NDJSON lines)","Update @tursodatabase/serverless to the latest patch release in case of runtime compatibility fixes","Report to Turso if the raw HTTP exchange shows 200-with-empty-body from the server itself"],"exampleFix":"// before (test mock without a body)\nglobalThis.fetch = async () => new Response('', { status: 200 });\n\n// after\nconst body = new ReadableStream({\n  start(c) {\n    c.enqueue(new TextEncoder().encode('{\"baton\":null,\"base_url\":null}\\n'));\n    c.close();\n  },\n});\nglobalThis.fetch = async () => new Response(body, { status: 200 });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { DatabaseError } from '@tursodatabase/serverless';\n\nfunction isNoBody(e: unknown): e is DatabaseError {\n  return e instanceof DatabaseError && e.message === 'No response body';\n}","tryCatchPattern":"try {\n  return await session.execute(sql, args);\n} catch (e) {\n  if (isNoBody(e)) throw new Error('server returned 200 with no body — check fetch polyfill/proxy');\n  throw e;\n}","preventionTips":["When mocking fetch in tests, always give the Response a ReadableStream body of NDJSON lines","Verify streaming works through every intermediary (proxies, devtools, service workers) after infrastructure changes","Keep @tursodatabase/serverless updated alongside runtime upgrades"],"tags":["http","streaming","protocol","testing"],"backgroundTag":"empty-response-body","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}