Skip to content

Interceptors returning null in React native caused by breaking change in msw 2.14.0 #2748

Description

@williamsaar

Prerequisites

Environment check

  • I'm using the latest msw version
  • I'm using Node.js version 20 or higher

Node.js version

24

Reproduction repository

https://github.com/williamsaar

Reproduction steps

I am using msw for tests in React native. We're using RTK Query for fetching data and msw to intercept those requests with mocked data for our tests. When updating msw from 2.12.4 to 2.14.6 the tests no longer worked because RTK Query received null for all requests, instead of our mocked data.

  1. React Native project using MSW for tests (e.g. Jest + RNTL).
  2. Handler returning JSON: http.get('/api/foo', () => HttpResponse.json({ ok: true })).
  3. Consumer reads body: const data = await response.json() or via RTK Query transformResponse.
  4. With MSW ≤2.12.x: body is received correctly.
  5. With MSW ≥2.14.0: body is null / "".

This was caused by an update to the @mswjs/interceptors lib PR #778 - released as v0.41.7 on April 29, 2026, the same day as MSW 2.14.0.

Root cause

@mswjs/interceptors PR #778 - released as v0.41.7 on April 29, 2026, the same day as MSW 2.14.0.

What changed in interceptors v0.41.7

In FetchInterceptor's respondWith, the body construction changed from:

// BEFORE (≤v0.41.6) — safe for React Native
const response = decompressedStream === null
  ? rawResponse                                        // ← passes rawResponse as-is
  : new FetchResponse(decompressedStream, rawResponse)
FetchResponse.setUrl(request.url, response)

to:

// AFTER (v0.41.7+) — breaks React Native
const response = new FetchResponse(
  decompressedStream || rawResponse.body,              // ← reads .body
  { url: request.url, status: ..., statusText: ..., headers: ... }
)

Why it breaks React Native

React Native's whatwg-fetch polyfill stores the body as _bodyText and doesn't expose a .body getter returning a ReadableStream. So rawResponse.body is undefined, new FetchResponse(undefined, ...) gets a null body, and .text() returns "" - which RTK Query's transformResponse sees as null.

The connection to MSW versions

  • MSW 2.12.14 -> USed "@mswjs/interceptors": "^0.41.2", which resolved to ≤0.41.3, which still used the safe rawResponse passthrough.
  • MSW 2.14.0 -> Used "@mswjs/interceptors": "^0.41.3", released the same day as interceptors v0.41.7, so a fresh install resolves to 0.41.7, pulling in the breaking body change.

Workaround

Adding this to the msw.polyfill.js patches the Response.prototype.body top return _bodyText:

if (
  typeof global.Response !== "undefined" &&
  !Object.getOwnPropertyDescriptor(global.Response.prototype, "body")
) {
  Object.defineProperty(global.Response.prototype, "body", {
    get() {
      const text = this._bodyText;
      return text != null ? text : null;
    },
    configurable: true,
  });
}

Full msw.polyfill.js for reference:

import "fast-text-encoding";
import "react-native-url-polyfill/auto";

function defineMockGlobal(name) {
  if (typeof global[name] === "undefined") {
    global[name] = class {
      constructor(type, eventInitDict) {
        this.type = type;
        Object.assign(this, eventInitDict);
      }
    };
  }
}

["MessageEvent", "Event", "EventTarget", "BroadcastChannel"].forEach(defineMockGlobal);

if (
  typeof global.Response !== "undefined" &&
  !Object.getOwnPropertyDescriptor(global.Response.prototype, "body")
) {
  Object.defineProperty(global.Response.prototype, "body", {
    get() {
      const text = this._bodyText;
      return text != null ? text : null;
    },
    configurable: true,
  });
}

Current behavior

rawResponse.body is undefined in React Native's polyfill, so new FetchResponse(undefined, ...) is constructed with a null body.

Expected behavior

Mocked response body is forwarded correctly to the React Native fetch consumer regardless of whether the underlying Response polyfill exposes .body as a ReadableStream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds:triageIssues that have not been investigated yet.scope:nodeRelated to MSW running in Node

    Type

    No type

    Fields

    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