marmelab/react-admin · error · Error
useListController received a React element as `filter` props
Error message
useListController received a React element as `filter` props. If you intended to set the list filter elements, use the `filters` (with an s) prop instead. The `filter` prop is internal and should not be set by the developer.
What it means
As with InfiniteList, `filter` must be a plain filter-values object for useListController; React elements (singly or inside arrays) belong in the `filters` prop. The controller throws when it detects an element in `filter`.
Source
Thrown at packages/ra-core/src/controller/list/useListController.ts:78
perPage = 10,
queryOptions = {},
sort = defaultSort,
storeKey,
} = props;
const resource = useResourceContext(props);
const { meta, ...otherQueryOptions } = queryOptions;
if (!resource) {
throw new Error(
`useListController requires a non-empty resource prop or context`
);
}
if (
filter &&
(isValidElement(filter) ||
(Array.isArray(filter) && filter.some(isValidElement)))
) {
throw new Error(
'useListController received a React element as `filter` props. If you intended to set the list filter elements, use the `filters` (with an s) prop instead. The `filter` prop is internal and should not be set by the developer.'
);
}
const { isPending: isPendingAuthenticated } = useAuthenticated({
enabled: !disableAuthentication,
});
const { isPending: isPendingCanAccess } = useRequireAccess<RecordType>({
action: 'list',
resource,
enabled: !disableAuthentication && !isPendingAuthenticated,
});
const translate = useTranslate();
const notify = useNotify();
const dataProvider = useDataProvider();
View on GitHub (pinned to 051f511bb0)
Solutions
- Rename the prop to `filters` for filter inputs: filters={[<PostFilter/>]}>
- Keep `filter` as a plain object of values: filter={{ status: 'open' }}
- Search the codebase for `filter={` and `filter={[` JSX usages on list components
Example fix
// before
<List filter={[<SearchInput source="q" />} />
// after
<List filters={[<SearchInput source="q" />]} />
<List filter={{ status: 'open' }} /> // object is fine Defensive patterns
Strategy: validation
Validate before calling
if (isValidElement(props.filter) || (Array.isArray(props.filter) && props.filter.some(isValidElement))) {
throw new Error('filter must be an object; use filters for inputs');
} Type guard
const isFilterValuesObject = (f: unknown): f is Record<string, any> => f === undefined || (typeof f === 'object' && f !== null && !Array.isArray(f) && !React.isValidElement(f));
Try / catch
try { render(<List filter={badFilter} />); } catch (e) { if (String(e).includes('filters` (with an s)')) { /* move element to filters prop */ } } Prevention
- Type filter as Record<string, any> in wrapper components so JSX is a compile error
- Grep for `filter={[` and `filter={<` in list usages
- Document filter vs filters in your team's react-admin guide
When it happens
Trigger: <List filter={[<MyFilter/>]}> or filter={<MyFilter/>}; an array containing at least one element also triggers it.
Common situations: Copy-pasting old react-admin v2 examples where filter accepted elements; confusing `filter` vs `filters`; building filter arrays dynamically and accidentally including JSX.
Related errors
- <InfiniteList> received a React element as `filter` props. I
- Cannot use alwaysOn and defaultValue on a filter input. Plea
- 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
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/f25ce45a8b24de73.
Report an issue: GitHub.