marmelab/react-admin · error · Error
DatagridRow expects an id prop
Error message
DatagridRow expects an id prop
What it means
Inside <Datagrid>, each row (DatagridRow) needs the record id to build selection state, row click handlers, and expansion keys. The expand-content variant of DatagridRow destructures `id` from props and throws immediately when it is undefined, since rows without ids cannot participate in the datagrid's row identity logic.
Source
Thrown at packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx:60
> = React.forwardRef<HTMLTableRowElement, DatagridRowProps>((props, ref) => {
const {
children,
className,
expand,
hasBulkActions = false,
hover = true,
id,
onToggleItem,
record: recordOverride,
rowClick,
selected = false,
style,
selectable = true,
...rest
} = props;
if (typeof id === 'undefined') {
throw new Error('DatagridRow expects an id prop');
}
const context = useDatagridContext();
const translate = useTranslate();
const record = useRecordContext(props);
if (!record) {
throw new Error(
'DatagridRow can only be used within a RecordContext or be passed a record prop'
);
}
const resource = useResourceContext(props);
const resourceDefinition = useResourceDefinition(props);
const hasDetailView =
resourceDefinition.hasShow || resourceDefinition.hasEdit;
if (!resource) {
throw new Error(
'DatagridRow can only be used within a ResourceContext or be passed a resource prop'
);
}View on GitHub (pinned to 051f511bb0)
Solutions
- Forward all row props to DatagridRow, including id: `<DatagridRow {...props} />`.
- When using DatagridRow directly, pass `id={record.id}`.
- In custom wrappers, explicitly destructure and re-pass `id`.
Example fix
// before
const MyRow = ({ id, ...rest }) => <DatagridRow {...rest} />;
// after
const MyRow = (props) => <DatagridRow {...props} />; Defensive patterns
Strategy: type-guard
Validate before calling
rows.forEach(r => { if (r.id == null) throw new Error('dataProvider returned a row without id'); }); Type guard
const hasId = (r: Record<string, unknown> & { id?: unknown }): r is { id: Identifier } =>
r.id !== undefined && r.id !== null; Prevention
- Always spread {...props} from custom row wrappers into DatagridRow.
- Ensure the dataProvider normalizes every record to have an `id`.
- Add a dev-time assertion that mapped records contain ids.
When it happens
Trigger: Rendering a custom row component (row via `<Datagrid row={...}>` or expand panel) that does not forward the `id` prop down to DatagridRow, or using DatagridRow directly without an id.
Common situations: Wrapping DatagridRow in a custom component that filters out unknown props (including id); building a custom expand renderer and forgetting `{...props}` passthrough; TypeScript not catching it because props were spread loosely.
Related errors
- useReferenceFieldController: missing reference prop. You mus
- useShowController requires an id prop or a route with an /:i
- useNextPrevController was called outside of a ResourceContex
- To create a new option, you must pass an onCreate function o
- <InfiniteListBase> requires either a 'render' prop or 'child
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/cc733086980082e8.
Report an issue: GitHub.