marmelab/react-admin · error · Error

useSimpleFormIteratorItem must be used inside a SimpleFormIt

Error message

useSimpleFormIteratorItem must be used inside a SimpleFormIteratorItem

What it means

useSimpleFormIteratorItem reads SimpleFormIteratorItemContext, provided per-row by <SimpleFormIteratorItem>. Called outside a row context, the hook has nothing meaningful to return (index, item, remove), so react-admin throws immediately.

Source

Thrown at packages/ra-core/src/controller/input/useSimpleFormIteratorItem.ts:13

import { useContext } from 'react';
import { SimpleFormIteratorItemContext } from './SimpleFormIteratorItemContext';

/**
 * A hook that provides access to a SimpleFormIterator item meta (its index and the total number of items) and mutators (reorder and remove this remove).
 * Useful to create custom array input iterators.
 * @see {SimpleFormIterator}
 * @see {ArrayInput}
 */
export const useSimpleFormIteratorItem = () => {
    const context = useContext(SimpleFormIteratorItemContext);
    if (!context) {
        throw new Error(
            'useSimpleFormIteratorItem must be used inside a SimpleFormIteratorItem'
        );
    }
    return context;
};

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Ensure the calling component is rendered inside <SimpleFormIteratorItem> (normally wrap your custom input inside the iterator's children).
  2. Update custom SimpleFormIterator replacements to provide SimpleFormIteratorItemContext per row when migrating to newer react-admin versions.
  3. If you only need array-level API, use useSimpleFormIterator instead of the item hook.

Example fix

// before: item hook used at iterator level
<SimpleFormIterator>
  <MyItemLabel /> {/* throws: no item context here */}
</SimpleFormIterator>
// after: ensure the consumer renders inside the item provider (default iterator rows)
<SimpleFormIterator>
  <TextField source="name" /> {/* rendered per row inside SimpleFormIteratorItem */}
</SimpleFormIterator>
Defensive patterns

Strategy: type-guard

Type guard

const isInsideSimpleFormIteratorItem = (ctx: SimpleFormIteratorItemContextValue | null): ctx is SimpleFormIteratorItemContextValue =>
  ctx != null && typeof ctx.index === 'number';

Try / catch

try {
  const { index, remove } = useSimpleFormIteratorItem();
} catch (e) {
  if (e.message.includes('useSimpleFormIteratorItem must be used inside')) {
    console.error('Component must be rendered inside a SimpleFormIterator row');
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling useSimpleFormIteratorItem in a component that is not rendered by <SimpleFormIteratorItem> — e.g. directly inside <SimpleFormIterator> children but outside the item wrapper, or anywhere in the form unrelated to array rows.

Common situations: Custom row inputs that read the item context but are used in iterators that render children differently (older react-admin versions wrapped only fields, not every child); moving a row component out of the iterator; version upgrades where the item context provider was introduced and custom iterators were not updated.

Related errors


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