twentyhq/twenty · error · Error
download returned no body
Error message
download returned no body
What it means
After the content-length checks pass, the downloader asserts `response.body` is a non-null `ReadableStream`. A null body means the fetch runtime did not provide a stream to read from, so there is nothing to upload; the code throws rather than proceed. This is distinct from a missing content-length (26) or a non-ok status (25).
Source
Thrown at packages/twenty-apps/public/call-recorder/src/logic-functions/flows/import-call-recording-media.util.ts:231
fileName,
body: response.body,
});
throw new Error('download response is missing content-length');
}
if (contentLengthBytes > maxMediaFileSizeBytes) {
await cancelMediaDownloadBody({
callRecordingId,
fileName,
body: response.body,
});
return { outcome: 'too-large', sizeBytes: contentLengthBytes };
}
if (isNull(response.body)) {
throw new Error('download returned no body');
}
return {
outcome: 'opened',
body: response.body,
sizeBytes: contentLengthBytes,
};
};
const uploadMediaStreamToStorage = async ({
callRecordingId,
metadataClient,
fileName,
fieldMetadataUniversalIdentifier,
body,
sizeBytes,
}: {
callRecordingId: string;View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Confirm the runtime/polyfill providing `fetch` supports `ReadableStream` bodies (Node 18+ undici does; older polyfills may not).
- Ensure nothing consumes `response.body` (e.g. a logging hook calling `.json()`/`.text()`) before this point.
- If the host genuinely returns empty bodies for some artifacts, guard earlier and mark that artifact as unavailable instead of throwing.
- Log `response.headers` and status alongside the null-body check to distinguish a host issue from a runtime issue.
Example fix
// before
if (isNull(response.body)) {
throw new Error('download returned no body');
}
// after — distinguish runtime-missing-stream from host-empty-body
if (isNull(response.body)) {
throw new Error(
`download returned no body for ${fileName} (status=${response.status}, contentLength=${contentLengthBytes}); fetch runtime may not expose ReadableStream bodies`,
);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the runtime exposes a streaming fetch body before importing media.
if (typeof Response === 'undefined' || typeof ReadableStream === 'undefined') {
throw new Error('Runtime does not support streaming response bodies; cannot import media');
} Type guard
const hasStreamingBody = (res: Response): res is Response & { body: ReadableStream<Uint8Array> } =>
!isNull(res.body) && typeof (res.body as ReadableStream<Uint8Array>).getReader === 'function'; Prevention
- Run the media-import logic function in a runtime with native streaming fetch (Node 18+ undici).
- Do not consume `response.body` (e.g. via `.json()`/`.text()`) in logging hooks before the download path reads it.
- Log status + headers at the null-body check to distinguish host-empty-body from runtime-no-stream.
- Pin the runtime version so a regression in fetch body support is caught immediately.
When it happens
Trigger: The fetch implementation in use does not expose streaming bodies (some runtimes/polyfills return `body: null`), the response was already consumed/cancelled upstream, or the media host returned a 2xx with an empty body that the runtime represents as null.
Common situations: Running the logic function in a runtime whose `fetch` does not implement streaming bodies; a polyfill mismatch; or a logic-function platform update that changed how response bodies are exposed.
Related errors
- download failed with status ${response.status}
- download response is missing content-length
- failed to request artifact import for call recording ${callR
- RECALL_WEBHOOK_SECRET server variable is not set. A server a
- Raw request body was not forwarded by the server; cannot ver
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/4d140c7911fe0311.
Report an issue: GitHub.