mastra-ai/mastra · error
No response body
Error message
No response body
What it means
In agent.ts subscribeToThread(), after subscribing to a thread's stream the client checks streamResponse.body and throws 'No response body' if it is missing, since the returned subscription object needs a ReadableStream to process agent thread data chunks. This is an early guard before wiring up processDataStream and abort handlers.
Source
Thrown at client-sdks/client-js/src/resources/agent.ts:642
unsubscribe: () => void;
}
> {
const { resourceId, threadId } = params;
const requestSubscription = () =>
this.request(`/agents/${this.agentId}/threads/subscribe`, {
method: 'POST',
body: { resourceId, threadId },
stream: true,
}) as Promise<Response>;
const streamResponse = (await requestSubscription()) as Response & {
processDataStream: (options: ProcessAgentThreadStreamOptions) => Promise<void>;
abort: () => Promise<boolean>;
unsubscribe: () => void;
};
if (!streamResponse.body) {
throw new Error('No response body');
}
const agent = this;
streamResponse.abort = async () => (await agent.abortThread({ resourceId, threadId })).aborted;
let unsubscribed = false;
let processAbortController: AbortController | undefined;
let processStarted = false;
streamResponse.unsubscribe = () => {
if (unsubscribed) return;
unsubscribed = true;
processAbortController?.abort();
if (!processStarted) {
void streamResponse.body?.cancel().catch(() => {});
}
};
View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure the server's thread subscribe endpoint streams data (test with curl -N).
- Fix test mocks to supply a ReadableStream body.
- Upgrade to an environment with native streaming fetch (modern browsers, Node 18+).
- Check proxies/CDNs (e.g. buffering middleware) aren't stripping the stream.
- Try/catch around subscribeToThread and fall back to polling thread messages.
Example fix
// before
const sub = await agent.subscribeToThread({ resourceId, threadId });
// after
try {
const sub = await agent.subscribeToThread({ resourceId, threadId });
} catch (e) {
if ((e as Error).message === 'No response body') {
console.error('Subscribe returned no body — falling back to polling');
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(subscribeUrl);
if (res.ok && !res.body) throw new Error('Thread subscribe returns no body in this environment'); Type guard
function hasBody(res: Response): res is Response & { body: ReadableStream<Uint8Array> } { return res.body != null; } Try / catch
try {
const sub = await agent.subscribeToThread({ resourceId, threadId });
} catch (err) {
if ((err as Error).message === 'No response body') {
console.error('Subscribe got no stream body — check mocks/proxies, consider polling thread messages');
}
throw err;
} Prevention
- Mock subscribe endpoints with ReadableStream bodies
- Verify subscribe endpoint streams in the target environment
- Avoid CDN/proxy buffering on SSE routes
- Provide a polling fallback for thread messages
When it happens
Trigger: The thread subscription request returns ok but body is null: mocks without a body, buffering infrastructure on the subscribe route, or a fetch implementation without streaming bodies.
Common situations: Frontend tests mocking the thread subscribe endpoint with only { ok: true }; gateways/CDNs buffering the SSE stream to empty; older polyfilled fetch in legacy browsers or constrained runtimes.
Related errors
- No response body for agent controller session stream
- UI Messages require a data property when using data- prefixe
- UI Messages require a data property when using data- prefixe
- UI Messages require a data property when using data- prefixe
- MastraClient.deleteThread() requires exactly one of agentId
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/54e62c389daee9ca.
Report an issue: GitHub.