marmelab/react-admin · error · Error

SelectRowTableCell can only be used within a RecordContext

Error message

SelectRowTableCell can only be used within a RecordContext

What it means

SelectRowCheckbox (rendered in SelectRowTableCell) reads the current record via useRecordContext to determine selection state and selectability. With no record in context it cannot compute `record.id`, so react-admin throws immediately.

Source

Thrown at packages/ra-ui-materialui/src/list/datatable/SelectRowCheckbox.tsx:19

import React, { useCallback, memo } from 'react';
import { Checkbox } from '@mui/material';
import {
    useDataTableSelectedIdsContext,
    useDataTableCallbacksContext,
    useTranslate,
    useRecordContext,
} from 'ra-core';

import { DataTableClasses } from './DataTableRoot';

export const SelectRowCheckbox = memo(() => {
    const { handleToggleItem, isRowSelectable } =
        useDataTableCallbacksContext();
    const selectedIds = useDataTableSelectedIdsContext();
    const translate = useTranslate();
    const record = useRecordContext();
    if (!record) {
        throw new Error(
            'SelectRowTableCell can only be used within a RecordContext'
        );
    }

    const selectable = !isRowSelectable || isRowSelectable(record);
    const selected = selectedIds?.includes(record.id);

    const handleToggleSelection = useCallback(
        event => {
            if (!selectable || !handleToggleItem) return;
            handleToggleItem(record.id, event);
            event.stopPropagation();
        },
        [record.id, handleToggleItem, selectable]
    );

    return (
        <Checkbox

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Render the cell within <DataTableRow> or wrap it in <RecordContextProvider value={record}>.
  2. Use <DataTable> inside a <List> so both record and callback contexts are populated.
  3. Remove the select cell from rows that intentionally have no record.

Example fix

// before
<TableCell><SelectRowTableCell /></TableCell>
// after
<RecordContextProvider value={record}>
  <TableCell><SelectRowTableCell /></TableCell>
</RecordContextProvider>
Defensive patterns

Strategy: validation

Validate before calling

const record = useRecordContext();
if (!record) return null; // or throw before rendering SelectRowTableCell

Type guard

const hasRecord = (r: RaRecord | null | undefined): r is RaRecord => !!r && typeof r.id !== 'undefined';

Try / catch

try { renderCell(); } catch (e) { if (String(e).includes('SelectRowTableCell')) return null; throw e; }

Prevention

When it happens

Trigger: Rendering <SelectRowTableCell> in a table row outside a RecordContext, e.g. a header row or a custom cell not wrapped by <RecordContextProvider>.

Common situations: Custom DataTable configurations where the select cell is placed outside <DataTableRow>, or manual <Table> assembly without a record scope.

Related errors


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