marmelab/react-admin · error · Error
ra.navigation.page_out_of_boundaries
Error message
ra.navigation.page_out_of_boundaries
What it means
Pagination guards against out-of-range page changes from the MUI TablePagination input (page is 0-based internally; the message shows page+1). If the user somehow navigates to page < 0 or beyond the last page, react-admin throws a translated ra.navigation.page_out_of_boundaries error.
Source
Thrown at packages/ra-ui-materialui/src/list/pagination/Pagination.tsx:52
setPerPage,
} = useListPaginationContext();
const translate = useTranslate();
const isSmall = useMediaQuery((theme: Theme) =>
theme.breakpoints.down('md')
);
const totalPages = useMemo(() => {
return total != null ? Math.ceil(total / perPage) : undefined;
}, [perPage, total]);
/**
* Warning: Material UI's page is 0-based
*/
const handlePageChange = useCallback(
(event, page) => {
event && event.stopPropagation();
if (page < 0 || (totalPages && page > totalPages - 1)) {
throw new Error(
translate('ra.navigation.page_out_of_boundaries', {
page: page + 1,
})
);
}
setPage(page + 1);
},
[totalPages, setPage, translate]
);
const handlePerPageChange = useCallback(
event => {
setPerPage(event.target.value);
},
[setPerPage]
);
const labelDisplayedRows = useCallback(View on GitHub (pinned to 051f511bb0)
Solutions
- Clamp the page passed to the list controller (setPage) within 0..totalPages-1.
- Ensure totalPages/total are correctly supplied by the dataProvider (json-server style X-Total-Count).
- Reset the page when filters change (List does this automatically; avoid overriding page outside useListContext).
Example fix
// before setPage(newPage); // after const safePage = Math.max(0, Math.min(newPage, (totalPages ?? newPage + 1) - 1)); setPage(safePage);
Defensive patterns
Strategy: try-catch
Validate before calling
const inBounds = (page: number, totalPages?: number) => page >= 0 && (!totalPages || page <= totalPages - 1); if (!inBounds(page, totalPages)) setPage(Math.max(0, (totalPages ?? 1) - 1));
Type guard
const isValidPage = (p: unknown, totalPages?: number): p is number => typeof p === 'number' && Number.isInteger(p) && p >= 0 && (totalPages == null || p <= totalPages - 1);
Try / catch
error => { if (error.message === 'ra.navigation.page_out_of_boundaries' || error.message.includes('page_out_of_boundaries')) { setPage(1); return; } throw error; } Prevention
- Reset page to 1 whenever filters/sort change.
- Keep total accurate in the dataProvider response.
- Clamp user-entered page numbers before setPage.
When it happens
Trigger: Total/totalPages shrinking (e.g. after a filter or delete) while the current page number remains high, or manual page entry beyond the last page.
Common situations: Deleting all records on the last page, applying filters that reduce totalPages while page stays elevated, or custom pagination logic bypassing setPage bounds.
Related errors
- Found getManyReference result in cache without total or page
- 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
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/171dac4768fa18e5.
Report an issue: GitHub.