marmelab/react-admin · error · Error

cannot change the order on an undefined sort field

Error message

cannot change the order on an undefined sort field

What it means

The sortReducer handles SET_SORT_ORDER actions, which only toggle the order of an already-selected field. If the sort state has no field set, there is nothing to reorder, so the reducer throws rather than producing invalid state.

Source

Thrown at packages/ra-core/src/controller/useSortState.ts:35

const sortReducer = (state: SortPayload, action: Action): SortPayload => {
    switch (action.type) {
        case 'SET_SORT':
            return action.payload;
        case 'SET_SORT_FIELD': {
            const field = action.payload;
            const order =
                state.field === field
                    ? state.order === SORT_ASC
                        ? SORT_DESC
                        : SORT_ASC
                    : SORT_ASC;
            return { field, order };
        }
        case 'SET_SORT_ORDER': {
            const order = action.payload;
            if (!state.field) {
                throw new Error(
                    'cannot change the order on an undefined sort field'
                );
            }
            return {
                field: state.field,
                order,
            };
        }
        default:
            return state;
    }
};

export const defaultSort = { field: '', order: 'ASC' } as const;

/**
 * Set the sort { field, order }
 * @name setSort

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Dispatch SET_SORT_FIELD (or setSort with a full { field, order }) first instead of only setting the order
  2. Guard the call: only toggle order when the current sort field is non-empty
  3. Initialize the sort state with a default field, e.g. useSortState({ field: 'name', order: 'ASC' })

Example fix

// before
onClick={() => setSort({ order: order === 'ASC' ? 'DESC' : 'ASC' })}
// after
onClick={() =>
  sort.field
    ? setSort({ field: sort.field, order: order === 'ASC' ? 'DESC' : 'ASC' })
    : setSort({ field: 'name', order: 'ASC' })
}
Defensive patterns

Strategy: validation

Validate before calling

if (!sort.field) setSort({ field: DEFAULT_FIELD, order: 'ASC' }); else setSort({ field: sort.field, order: next });

Type guard

const hasSortField = (s: { field: string }) => typeof s.field === 'string' && s.field.length > 0;

Try / catch

try { setSort({ order: nextOrder }); } catch { setSort({ field: defaultField, order: nextOrder }); }

Prevention

When it happens

Trigger: Dispatching SET_SORT_ORDER (or calling setSort({ order: 'ASC' }) / changeSortOrder) while the current sort state is { field: '', order: ... } — i.e. toggling order before any sort field was set (e.g. a table header sort control that only flips order, used before clicking a column).

Common situations: Custom sort toggle buttons wired to setSortOrder but initialized without a field; clearing sort (field '') then pressing the direction toggle; misusing useSortState in custom UIs where the initial sort was never set.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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