redux-toolkit icon indicating copy to clipboard operation
redux-toolkit copied to clipboard

TypeError: Cannot read properties of undefined (reading 'clone')

Open preetish-brine opened this issue 4 months ago • 10 comments

Error Details

  • Level: Error
  • Cannot read properties of undefined (reading 'clone')
  • Location: (@reduxjs/toolkit/dist/query/rtk-query.esm)
Image

Source Map

../../node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js in at line 269:46 ../../node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js in step at line 23:23 ../../node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js in Object.next at line 4:53 ../../node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js in fulfilled at line 70:32

Our Setup We’re using:

const baseQueryWithSessionHandler = async (args, api, extraOptions) => {
  ...
  const result = await baseQuery(adjustedArgs, api, extraOptions);
    if (result.data) {
      result.data = { ...result.data, statusCode: result.meta.response.status };
      return result;
    }
  ...
};

Wrapped in retry() and custom backoff:

const staggeredBaseQueryWithSessionHandler = retry(baseQueryWithSessionHandler, {
  backoff: customBackoff,
  maxRetries: 3,
  retryCondition: (error, args, { baseQueryApi, attempt }) => {
    return (
      args.method === 'GET' &&
      attempt < 3 &&
      error?.data?.message !== unauthorizedErrorMessage &&
      error?.status !== 401
    );
  },
});

After digging into the source of fetchBaseQuery and retry, we observed: meta is created and initially populated with request:

requestClone = request.clone();
meta = { request: requestClone };
Later, only if fetch() succeeds, response.clone() is called and attached to meta.response.

responseClone = response.clone();
meta.response = responseClone;
If the initial fetch fails (e.g. due to network or DNS issues), then meta.response is never set.

If a subsequent retry succeeds, the returned result includes data, but meta.response may still be missing

Image

preetish-brine avatar Aug 01 '25 06:08 preetish-brine

Can you provide a sandbox or repo that reproduces this issue? Seems extremely odd that there isn't a response here.

markerikson avatar Aug 01 '25 16:08 markerikson

https://codesandbox.io/p/sandbox/6lsqsm here is a sandbox @markerikson please check this and get back

preetish-brine avatar Sep 02 '25 10:09 preetish-brine

@preetish-brine I'm looking at the sandbox example app and I don't see any errors like this. Are there specific steps to reproduce? Does this demo actually show the error, or is it "just" the code you're using but the demo works fine?

markerikson avatar Sep 03 '25 01:09 markerikson

this just the code that we are using in the same flow exactly, this error is random and comes randomly the behaviour is very random hence its concerning @markerikson

preetish-brine avatar Sep 03 '25 04:09 preetish-brine

Any chance you could put together an updated version that actually shows this error happening with some consistency? Just based on that retry bit I can't see anything that seems like it would affect RTKQ's internals.

markerikson avatar Sep 03 '25 04:09 markerikson

Hmm. Actually, I missed reading the section about "if the fetch fails, meta.response isn't set". That seems plausible.

markerikson avatar Sep 03 '25 04:09 markerikson

Okay, yeah, I can see that if I force the fetchFn to return something that isn't a Response, the response.clone() line fails. However, that whole block of logic is written under the assumption that it did return a Response.

Can you give a working example of cases where fetch doesn't return a Response?

markerikson avatar Sep 03 '25 05:09 markerikson

This happens only a few times a day among many user sessions, so it’s almost certainly due to transient network instability rather than a deterministic code bug. It’s not reproducible in a controlled environment.

preetish-brine avatar Sep 03 '25 05:09 preetish-brine

We talked about this a bit, and the thing is that fetch is defined as returning Promise<Response>. If that's not happening, then it's a bug in the fetching function. We could technically check for it to return something else, but that shouldn't be happening.

Can you reproduce this at all without the retry behavior? Or describe a way to make this happen consistently?

Right now my inclination is to say "we rely on the spec here, and any violations of that are not a bug in RTK".

markerikson avatar Sep 04 '25 00:09 markerikson

Updated methods to make the sandbox support retry as well as random null responses , check index.tsx and comment / uncomment methods based on usage. https://codesandbox.io/p/sandbox/6lsqsm but yet to replicate this behaviour

preetish-brine avatar Sep 04 '25 10:09 preetish-brine