marmelab/react-admin · error · Error
refetch is not available for a ListContext built from useLis
Error message
refetch is not available for a ListContext built from useList based on local data
What it means
When a ListContext is created from local data via useList (no dataProvider), there is no server query to re-run, so refetch is intentionally a stub that throws. Calling it on such a context is an API misuse.
Source
Thrown at packages/ra-core/src/controller/list/useList.ts:16
import { useCallback, useEffect, useRef, useState } from 'react';
import get from 'lodash/get.js';
import isEqual from 'lodash/isEqual.js';
import { removeEmpty } from '../../util';
import { Exporter, FilterPayload, RaRecord, SortPayload } from '../../types';
import { useResourceContext } from '../../core';
import usePaginationState from '../usePaginationState';
import useSortState from '../useSortState';
import { useRecordSelection } from './useRecordSelection';
import { GetDataOptions, ListControllerResult } from './useListController';
import { flattenObject } from '../../dataProvider/fetch';
import { defaultExporter } from '../../export';
const refetch = () => {
throw new Error(
'refetch is not available for a ListContext built from useList based on local data'
);
};
/**
* Handle filtering, sorting and pagination on local data.
*
* Returns the data and callbacks expected by <ListContext>.
*
* @example
* const data = [
* { id: 1, name: 'Arnold' },
* { id: 2, name: 'Sylvester' },
* { id: 3, name: 'Jean-Claude' },
* ]
*
* const MyComponent = () => {
* const listContext = useList({ data });View on GitHub (pinned to 051f511bb0)
Solutions
- Don't call refetch on local-data lists; re-render by updating the source data state
- Conditionally render a refresh button only when the list is backed by a dataProvider
- Switch to a dataProvider-backed List/useListController if server refresh is needed
- Use a custom refresh handler that resets your local data instead of refetch
Example fix
// before
const { refetch } = useListContext();
<Button onClick={() => refetch()} /> // throws on local data
// after
const listContext = useListContext();
{listContext.data && <Button onClick={() => setLocalData(freshData)} />}
// or check availability: typeof refetch === 'function' Defensive patterns
Strategy: type-guard
Validate before calling
const listContext = useListContext(); const canRefetch = typeof listContext.refetch === 'function' && !isLocalDataList; if (canRefetch) listContext.refetch();
Type guard
const refetchIsAvailable = (ctx: ListControllerResult): ctx is ListControllerResult & { refetch: () => void } =>
typeof ctx.refetch === 'function'; Try / catch
try { refetch(); } catch (e) { if (String(e).includes('local data')) { /* refresh local state instead */ } } Prevention
- Only expose refresh buttons for dataProvider-backed lists
- Track whether the list uses `data` prop (local) vs dataProvider
- Write a component test exercising refetch on your local-data setup
When it happens
Trigger: Calling listContext.refetch() from useListContext when the list was built with <ListContextProvider value={useList({ data: localArray })}> or <ArrayField>-based contexts.
Common situations: Custom list views over local arrays; testing components with mock local data then reusing the same component against context.refetch; adding a refresh button to a local-data list.
Related errors
- useCanAccess must be used inside a <Resource> component or p
- useCreateController requires a non-empty resource prop or co
- useEditController requires a non-empty resource prop or cont
- useEditController requires an id prop or a route with an /:i
- useEditController: Fetched record's id attribute (${record.i
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/eacb5a7d7443b444.
Report an issue: GitHub.