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

SimpleFormIterator is the default iterator body of <ArrayInput>. It derives its source from the surrounding input via useWrappedSource(''); if there is no wrapped source (i.e., it is not inside an iterator input like ArrayInput), it cannot know which array field to iterate and throws.

Source

Thrown at packages/ra-core/src/test-ui/SimpleFormIterator.tsx:196

        addButton = <DefaultAddItemButton />,
        removeButton,
        reOrderButtons,
        children,
        className,
        resource,
        disabled,
        disableAdd = false,
        disableClear,
        disableRemove = false,
        disableReordering,
        inline,
        getItemLabel = false,
        fullWidth,
    } = props;

    const finalSource = useWrappedSource('');
    if (!finalSource) {
        throw new Error(
            'SimpleFormIterator can only be called within an iterator input like ArrayInput'
        );
    }

    const [confirmIsOpen, setConfirmIsOpen] = useState<boolean>(false);
    const { fields, remove } = useArrayInput(props);
    const translate = useTranslate();

    const handleArrayClear = useCallback(() => {
        remove();
        setConfirmIsOpen(false);
    }, [remove]);

    const records = useFieldValue({ source: finalSource });
    const getArrayInputNewItemDefaults =
        useGetArrayInputNewItemDefaults(fields);

    const getItemDefaults = useEvent((item: any = undefined) => {

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Always nest it inside an input that provides the array context: <ArrayInput source="tags"><SimpleFormIterator>...</SimpleFormIterator></ArrayInput>
  2. If you need custom array UI outside ArrayInput, build it with useFieldArray from react-hook-form instead of reusing SimpleFormIterator
  3. Ensure any wrapper component you create forwards children into ArrayInput rather than replacing it

Example fix

// before
<SimpleForm>
  <SimpleFormIterator>{...}</SimpleFormIterator>
</SimpleForm>

// after
<SimpleForm>
  <ArrayInput source="tags">
    <SimpleFormIterator>{...}</SimpleFormIterator>
  </ArrayInput>
</SimpleForm>
Defensive patterns

Strategy: validation

Validate before calling

// Ensure ArrayInput is the parent before rendering the iterator
<ArrayInput source="tags">
  {tags != null ? <SimpleFormIterator /> : null}
</ArrayInput>

Type guard

const isInArrayInput = (children: React.ReactNode, ctx: React.Context<unknown>) =>
  React.useContext(ctx) != null; // via useArrayInput's context in a wrapper component

Prevention

When it happens

Trigger: Using <SimpleFormIterator> directly inside a <SimpleForm> without an <ArrayInput> parent; rendering it in a custom input that is not an iterator context; placing it inside ArrayInput's wrong slot that bypasses the Form iterator context (e.g. outside via useArrayInput failing later).

Common situations: Reusing SimpleFormIterator for display outside forms; copy-pasting form markup where ArrayInput was deleted; building custom array editors without the required parent input.

Related errors


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