marmelab/react-admin · error
SimpleFormIterator can only be called within an iterator inp
Error message
SimpleFormIterator can only be called within an iterator input like ArrayInput
What it means
SimpleFormIteratorBase manages the rows of an array field; it discovers the field source via useWrappedSource(''), which is only populated inside an iterator context (ArrayInput). If the resolved source is empty it means the component is not inside an ArrayInput, so row operations (append/remove/move) have no target and react-admin throws.
Source
Thrown at packages/ra-core/src/controller/input/SimpleFormIteratorBase.tsx:22
import { useWrappedSource } from '../../core/useWrappedSource';
import type { RaRecord } from '../../types';
import { useEvent } from '../../util';
import { useArrayInput } from './useArrayInput';
import { SimpleFormIteratorContext } from './SimpleFormIteratorContext';
const DefaultGetItemDefaults = item => item;
export const SimpleFormIteratorBase = (props: SimpleFormIteratorBaseProps) => {
const {
children,
getItemDefaults: getItemDefaultsProp = DefaultGetItemDefaults,
disableAutoFocus = false,
} = props;
const getItemDefaults = useEvent(getItemDefaultsProp);
const finalSource = useWrappedSource('');
if (!finalSource) {
throw new Error(
'SimpleFormIterator can only be called within an iterator input like ArrayInput'
);
}
const { append, fields, move, remove } = useArrayInput(props);
const { trigger, getValues } = useFormContext();
const removeField = useEvent((index: number) => {
remove(index);
const isScalarArray = getValues(finalSource).every(
(value: any) => typeof value !== 'object'
);
if (isScalarArray) {
// Trigger validation on the Array to avoid ghost errors.
// Otherwise, validation errors on removed fields might still be displayed
trigger(finalSource);
}
});View on GitHub (pinned to 051f511bb0)
Solutions
- Wrap it in <ArrayInput source="items"><SimpleFormIterator>...</SimpleFormIterator></ArrayInput>
- For a generic repeater outside react-admin forms, use react-hook-form's useFieldArray directly
- In tests, render inside a full <Form><ArrayInput> structure
Example fix
// before
<TextInput source="title" />
<SimpleFormIterator>
<TextInput source="name" />
</SimpleFormIterator>
// after
<ArrayInput source="items">
<SimpleFormIterator>
<TextInput source="name" />
</SimpleFormIterator>
</ArrayInput> Defensive patterns
Strategy: validation
Validate before calling
const src = useWrappedSource('');
if (!src) throw new Error('Must be inside ArrayInput'); Type guard
const inArrayInput = (s: string | undefined): s is string => !!s && s.length > 0;
Try / catch
try {
render(<Form><SimpleFormIterator><TextInput source="name"/></SimpleFormIterator></Form>);
} catch (e) { logAndFallback(e); } Prevention
- Always wrap in <ArrayInput source=...]>
- Never use as generic repeater
- Assert wrapped source in custom wrappers
- Isolated tests for array forms
When it happens
Trigger: Rendering <SimpleFormIterator> outside <ArrayInput> (e.g. inside a regular TextInput, in a custom form section, or directly in a Show view); using it as a generic repeater without the array input wrapper.
Common situations: Reusing the iterator UI for ad-hoc repeatable fields; nesting mistakes where the iterator is placed under a different input component; tests rendering SimpleFormIterator standalone.
Related errors
- useArrayInput must be used inside an ArrayInputContextProvid
- SimpleFormIteratorItem must be used in a ResourceContextProv
- SimpleFormIterator can only be called within an iterator inp
- useSimpleFormIterator must be used inside a SimpleFormIterat
- useSimpleFormIteratorItem must be used inside a SimpleFormIt
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/f38dd23efc5c3f63.
Report an issue: GitHub.