{"record":{"id":"5f3fb2e4d20a2e2d","repo":"mastra-ai/mastra","slug":"response-body-is-null-5f3fb2","errorCode":null,"errorMessage":"Response body is null","messagePattern":"Response body is null","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client-sdks/client-js/src/resources/agent-builder.ts","lineNumber":210,"sourceCode":"    const searchParams = new URLSearchParams();\n    searchParams.set('runId', runId);\n\n    const requestContext = parseClientRequestContext(params.requestContext);\n    const { requestContext: _, ...actionParams } = params;\n\n    const url = `/agent-builder/${this.actionId}/stream?${searchParams.toString()}`;\n    const response: Response = await this.request(url, {\n      method: 'POST',\n      body: { ...actionParams, requestContext },\n      stream: true,\n    });\n\n    if (!response.ok) {\n      throw new Error(`Failed to stream agent builder action: ${response.statusText}`);\n    }\n\n    if (!response.body) {\n      throw new Error('Response body is null');\n    }\n\n    return response.body.pipeThrough(this.createRecordParserTransform());\n  }\n\n  /**\n   * Observes an existing agent builder action run stream.\n   * Replays cached execution from the beginning, then continues with live stream.\n   * This is the recommended method for recovery after page refresh/hot reload.\n   * This calls `/agent-builder/:actionId/observe`\n   */\n  async observeStream(params: { runId: string }): Promise<globalThis.ReadableStream<{ type: string; payload: any }>> {\n    const searchParams = new URLSearchParams();\n    searchParams.set('runId', params.runId);\n\n    const url = `/agent-builder/${this.actionId}/observe?${searchParams.toString()}`;\n    const response: Response = await this.request(url, {\n      method: 'POST',","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/client-sdks/client-js/src/resources/agent-builder.ts#L192-L228","documentation":"After an ok response from the agent-builder stream endpoint, the client requires a ReadableStream body to pipe through its record parser. A 2xx response with a null body cannot be streamed and triggers this throw.","triggerScenarios":"agentBuilder.stream(action, runId) receives an ok response whose body was consumed or never produced — fetch polyfills, response interceptors, or empty 2xx responses from a proxy.","commonSituations":"Test mocks returning Response without a body; react-native/polyfilled fetch without streaming support; middleware reading response.body before the client.","solutions":["Use a runtime with native streaming fetch support (Node 18+, modern browsers).","Remove interceptors/polyfills that consume the response body.","In tests, mock with a Response constructed from a real ReadableStream body."],"exampleFix":"// before\nmockFetch.mockResolvedValue(new Response(null, { status: 200 }));\n// after\nmockFetch.mockResolvedValue(new Response(someReadableStream, { status: 200 }));","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasBody(res: Response): res is Response & { body: ReadableStream<Uint8Array> } {\n  return res.body !== null;\n}","tryCatchPattern":"try {\n  const stream = await agentBuilder.stream(action, runId);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Response body is null') {\n    // streaming unsupported in this runtime; poll the action status instead\n  }\n  throw e;\n}","preventionTips":["Use runtimes with native streaming fetch support.","Don't intercept/consume the response body before the client reads it.","In tests, mock responses with real ReadableStream bodies."],"tags":["streaming","runtime","http"],"backgroundTag":"empty-response-body","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}