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

  1. Rename the prop to `filters` for filter inputs: filters={[<PostFilter/>]}>
  2. Keep `filter` as a plain object of values: filter={{ status: 'open' }}
  3. 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

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


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