marmelab/react-admin · error

<SortButton> MenuItems should have a data-sort attribute

Error message

<SortButton> MenuItems should have a data-sort attribute

What it means

SortButton renders menu items from its `fields` prop and reads a data-sort DOM attribute from the clicked menu item to know which field was chosen. If the clicked item lacks data-sort, the library throws instead of sorting on an unknown field. This usually means a custom MenuItem child was added without the attribute.

Source

Thrown at packages/ra-ui-materialui/src/button/SortButton.tsx:91

    const translateLabel = useTranslateLabel();
    const isXSmall = useMediaQuery((theme: Theme) =>
        theme.breakpoints.down('sm')
    );
    const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        setAnchorEl(event.currentTarget);
    };

    const handleClose = () => {
        setAnchorEl(null);
    };

    const handleChangeSort = (
        event: React.MouseEvent<HTMLLIElement, MouseEvent>
    ) => {
        const field = event.currentTarget.dataset.sort;
        if (!field) {
            throw new Error(
                '<SortButton> MenuItems should have a data-sort attribute'
            );
        }
        setSort({
            field,
            order: field === sort.field ? inverseOrder(sort.order) : 'ASC',
        });
        setAnchorEl(null);
    };

    const fieldLabel = translateLabel({
        resource,
        source: sort.field,
    });
    const buttonLabel = translate(label, {
        field: fieldLabel,
        field_lower_first:
            typeof fieldLabel === 'string'

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Add data-sort to every custom MenuItem: <MenuItem data-sort="title">Title</MenuItem>
  2. Only use SortButton's built-in children or keep custom ones compliant
  3. If adding separators/labels, ensure they don't use handleChangeSort (e.g. disable them)

Example fix

// before
<MenuItem>Title</MenuItem>
// after
<MenuItem data-sort="title">Title</MenuItem>
Defensive patterns

Strategy: validation

Validate before calling

const items = fields.map(f => ({ field: f, node: <MenuItem key={f} data-sort={f}>{labelFor(f)}</MenuItem> }));
// assert every custom child has data-sort before rendering
items.forEach(i => { if (!i.node.props['data-sort']) throw new Error('MenuItem missing data-sort'); });

Type guard

const hasDataSort = (el: React.ReactElement): el is React.ReactElement<{ 'data-sort': string }> =>
  typeof el.props['data-sort'] === 'string' && el.props['data-sort'].length > 0;

Prevention

When it happens

Trigger: Clicking a custom <MenuItem> child inside <SortButton> that does not set data-sort="fieldName"; overriding default menu items with ones missing the attribute.

Common situations: Customizing SortButton children to add icons or extra items and forgetting data-sort; passing non-MenuItem children the component wasn't designed for.

Related errors


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