marmelab/react-admin · error · Error

<FilterButton> must be called inside a ResourceContextProvid

Error message

<FilterButton> must be called inside a ResourceContextProvider, or must provide a resource prop

What it means

FilterButton supports saving queries, which is keyed per resource. When no resource is resolvable from context or props and saved queries are not disabled, react-admin throws because useSavedQueries needs a resource key.

Source

Thrown at packages/ra-ui-materialui/src/list/filter/FilterButton.tsx:59

export const FilterButton = (inProps: FilterButtonProps) => {
    const props = useThemeProps({
        props: inProps,
        name: PREFIX,
    });
    const {
        filters: filtersProp,
        className,
        disableSaveQuery,
        size,
        variant,
        ...rest
    } = props;
    const filters = useFilterContext() || filtersProp;
    const resource = useResourceContext(props);
    const translate = useTranslate();
    if (!resource && !disableSaveQuery) {
        throw new Error(
            '<FilterButton> must be called inside a ResourceContextProvider, or must provide a resource prop'
        );
    }
    const [savedQueries] = useSavedQueries(resource || '');
    const navigate = useNavigate();
    const {
        displayedFilters = {},
        filterValues,
        perPage,
        setFilters,
        showFilter,
        hideFilter,
        sort,
    } = useListContext();
    const hasFilterValues = !isEqual(filterValues, {});
    const validSavedQueries = extractValidSavedQueries(savedQueries);
    const hasSavedCurrentQuery = validSavedQueries.some(savedQuery =>
        isEqual(savedQuery.value, {

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Pass resource="posts" to <FilterButton>.
  2. Move FilterButton inside the <List> toolbar / ResourceContextProvider.
  3. Set disableSaveQuery if saved-query features are not needed and no resource is available.

Example fix

// before
<FilterButton filters={filters} />
// after
<FilterButton filters={filters} resource="posts" />
Defensive patterns

Strategy: validation

Validate before calling

const resource = useResourceContext(props);
if (!resource && !disableSaveQuery) { /* provide resource or set disableSaveQuery before rendering */ }

Type guard

const canRender = (p: { resource?: string; disableSaveQuery?: boolean }): p is { resource: string } => typeof p.resource === 'string' || p.disableSaveQuery === true;

Try / catch

try { renderFilterButton(); } catch (e) { if (String(e).includes('<FilterButton> must be called')) return <FilterButton resource="posts" {...props} />; throw e; }

Prevention

When it happens

Trigger: Rendering <FilterButton /> outside a ListContext/ResourceContextProvider without a resource prop while saved-query features are enabled (disableSaveQuery not set).

Common situations: Custom filter toolbars on non-list pages, or embedding FilterButton in a standalone layout without the resource.

Related errors


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