marmelab/react-admin · error · Error

Found getManyReference result in cache without total or page

Error message

Found getManyReference result in cache without total or pageInfo

What it means

After a delete, useDeleteMany updates the cached getManyReference result (the list of related records). The optimistic cache update needs to know the collection size, which it derives from either total (offset pagination) or pageInfo (cursor pagination). If neither field exists in the cached result, react-admin refuses to update it and throws.

Source

Thrown at packages/ra-core/src/dataProvider/useDeleteMany.ts:244

                        if (!recordWasFound) {
                            return res;
                        }
                        if (res.total) {
                            return {
                                ...res,
                                data: newCollection,
                                total:
                                    res.total -
                                    (res.data.length - newCollection.length),
                            };
                        }
                        if (res.pageInfo) {
                            return {
                                ...res,
                                data: newCollection,
                            };
                        }
                        throw new Error(
                            'Found getManyReference result in cache without total or pageInfo'
                        );
                    },
                    { updatedAt }
                );

                return params.ids;
            },
            getQueryKeys: ({ resource }) => {
                const queryKeys = [
                    [resource, 'getList'],
                    [resource, 'getInfiniteList'],
                    [resource, 'getMany'],
                    [resource, 'getManyReference'],
                ];
                return queryKeys;
            },
            onSettled: (...args) => {

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Make the data provider's getManyReference return { data, total } (or { data, pageInfo } for cursor pagination).
  2. Ensure the list query that populates the cache is fetched through useGetManyReference so the cache shape matches.
  3. If using a mock provider in tests, include total: data.length in getManyReference responses.

Example fix

// before
getManyReference: (resource, params) =>
  Promise.resolve({ data: filtered });
// after
getManyReference: (resource, params) =>
  Promise.resolve({ data: filtered, total: filtered.length });
Defensive patterns

Strategy: validation

Validate before calling

const res = await dataProvider.getManyReference(resource, params);
if (res.total == null && res.pageInfo == null) {
  throw new Error('getManyReference must return total or pageInfo');
}

Type guard

const hasListMeta = (r: { total?: number; pageInfo?: unknown }): r is { total: number } | { pageInfo: object } =>
  r.total != null || r.pageInfo != null;

Try / catch

try {
  await mutate(resource, { ids });
} catch (e) {
  if (e instanceof Error && e.message.includes('total or pageInfo')) {
    invalidateCache(); // refetch list without optimistic update
  } else throw e;
}

Prevention

When it happens

Trigger: A custom data provider returns getManyReference data without total and without pageInfo; the cache was populated by a non-standard query that shaped the result differently; calling useDeleteMany inside a ReferenceManyField-like list whose provider omits pagination metadata.

Common situations: Custom or third-party data providers that return only { data } from getManyReference; migrating a provider built for an older react-admin contract; mocking providers in tests that forget total/pageInfo.

Related errors


AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30). Data as JSON: /api/errors/e1be5a06f4b4eb2d. Report an issue: GitHub.