marmelab/react-admin · error · Error
When optionText returns a React element, you must also provi
Error message
When optionText returns a React element, you must also provide the inputText prop
What it means
After a selection is made, AutocompleteInput sets the input's filter value to the option label. When getOptionLabel yields a React element instead of a string (because optionText is an element and no valid inputText is configured) it cannot put an element into the text input, so it throws in a useEffect on selection change.
Source
Thrown at packages/ra-ui-materialui/src/input/AutocompleteInput.tsx:511
},
[
clearOnBlur,
field,
getOptionLabel,
selectedChoice,
filterValue,
debouncedSetFilter,
multiple,
]
);
useEffect(() => {
if (!multiple) {
const optionLabel = getOptionLabel(selectedChoice);
if (typeof optionLabel === 'string') {
setFilterValue(optionLabel);
} else {
throw new Error(
'When optionText returns a React element, you must also provide the inputText prop'
);
}
}
}, [getOptionLabel, multiple, selectedChoice]);
const handleInputChange: AutocompleteProps<
OptionType,
Multiple,
DisableClearable,
SupportCreate
>['onInputChange'] = useEvent((event, newInputValue, reason) => {
if (
event?.type === 'change' ||
!doesQueryMatchSelection(newInputValue)
) {
const createOptionLabel =
typeof createItemLabel === 'string'View on GitHub (pinned to 051f511bb0)
Solutions
- Ensure inputText is provided and returns a plain string for every choice
- If optionText is a function, return a string from it (or an object handled by getOptionLabelText with inputText set)
- Check that selectedChoice fields used by inputText are not undefined, which can make the label fall back to an element
Example fix
// before
<AutocompleteInput source="user" optionText={u => <span>{u.name}</span>} />
// after
<AutocompleteInput source="user" optionText={u => <span>{u.name}</span>} inputText={u => u.name} matchSuggestion={f => u => u.name.includes(f)} /> Defensive patterns
Strategy: validation
Validate before calling
// before rendering, verify every choice yields a string label via the configured inputText
const allLabelsAreStrings = choices.every(c => typeof inputText(c) === 'string');
if (!allLabelsAreStrings) throw new Error('inputText must return a string for every choice'); Type guard
const hasStringLabel = (
choice: unknown,
inputText?: (c: any) => any
): choice is { id: any } & Record<string, unknown> =>
typeof inputText?.(choice) === 'string'; Try / catch
try {
render(<AutocompleteInput optionText={elOptionText} inputText={inputText} />);
} catch (e) {
if (e.message.includes('optionText returns a React element')) {
console.error('inputText missing or non-string:', e.message);
}
} Prevention
- Ensure inputText returns a string, not JSX or undefined, for all choices
- Guard inputText against missing nested fields (e.g. choice.user?.name ?? '')
- Test selection behavior, not just initial render, for custom option elements
When it happens
Trigger: Selecting a choice in a single-value AutocompleteInput whose optionText resolves to a React element while inputText is absent or itself returns an element.
Common situations: Same root cause as errors 160-162 but surfacing later, at selection time rather than mount; typical when optionText is a function returning JSX, or inputText was omitted after a refactor.
Related errors
- emptyValue being set to null or undefined is not supported.
- optionText of type React element is not supported when setti
- If you provided a React element for the optionText prop, yo
- If you provided a React element for the optionText prop, yo
- useCanAccess must be used inside a <Resource> component or p
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/2b4ff1d6318bddd3.
Report an issue: GitHub.