Skip to content

Session Replay: capture fetch/binary (Blob, ArrayBuffer) response bodies in network detail #6376

Description

@antonis

Description

Mobile Session Replay network detail (added in #6288, with native option forwarding in #6373) inlines request/response bodies only when the underlying XMLHttpRequest.responseType is text-like ('', text, json). For binary response types (blob, arraybuffer, document) the SDK skips the body and surfaces [UNPARSEABLE_BODY_TYPE] instead:

// packages/core/src/js/replay/xhrUtils.ts — _getResponseBodyString
if (xhr.responseType === '' || xhr.responseType === 'text') return getBodyString(xhr.responseText);
if (xhr.responseType === 'json') return getBodyString(xhr.response);
// 'blob' / 'arraybuffer' / 'document' → not inlined:
return { _meta: { warnings: ['UNPARSEABLE_BODY_TYPE'] } };

Why this affects fetch specifically

In React Native, fetch is the whatwg-fetch polyfill built on XMLHttpRequest, and it sets xhr.responseType = 'blob'. So every fetch response body lands in the binary branch and shows [UNPARSEABLE_BODY_TYPE] in the Replay network tab, even though headers are captured normally. Requests made with a raw XMLHttpRequest (default text responseType, e.g. axios) are unaffected — their bodies are inlined.

Current vs. desired

  • Current: fetch responses → headers captured, body shown as [UNPARSEABLE_BODY_TYPE].
  • Desired: parseable binary/blob bodies (e.g. JSON or text returned as a Blob) are inlined like text bodies, respecting the existing ~150 KB cap and PII scrubbing.

Proposed approach

Read the Blob/ArrayBuffer body asynchronously (blob.text() / decoding the buffer) rather than skipping it. This is non-trivial because the current enrichment runs in the synchronous beforeAddBreadcrumb hook, whereas reading a blob is async — so it likely needs a separate async capture path (similar to how @sentry-internal/replay handles fetch bodies in the browser), with:

  • size cap (reuse NETWORK_BODY_MAX_SIZE) and truncation warning,
  • a parse timeout / abort handling,
  • keeping genuinely binary payloads (images, etc.) marked as unparseable.

Considerations

  • Should stay opt-in via networkDetailAllowUrls + networkCaptureBodies, with auth-like headers still stripped.
  • Request bodies for fetch (Request / RequestInit.body) would also need handling.

References

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions