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
- Pass resource="posts" to <FilterButton>.
- Move FilterButton inside the <List> toolbar / ResourceContextProvider.
- 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
- Keep FilterButton inside the default List actions/toolbar.
- Pass resource explicitly when embedding elsewhere.
- Set disableSaveQuery when no resource context exists.
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
- 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
- DataTableRow can only be used within a RecordContext or be p
- DataTableRow can only be used within a ResourceContext or be
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/648479bc15502b63.
Report an issue: GitHub.