marmelab/react-admin · warning

Input components require either a source or a name prop.

Error message

Input components require either a source or a name prop.

What it means

useInput resolves the input's identity and form registration from the source (or name) prop. When neither is provided the input cannot be registered with react-hook-form, so in development react-admin warns that the component is misconfigured.

Source

Thrown at packages/ra-core/src/form/useInput.ts:51

        name,
        onBlur: initialOnBlur,
        onChange: initialOnChange,
        parse: parseProp = defaultParse,
        source,
        validate,
        ...options
    } = props;
    const finalSource = useWrappedSource(source);
    const finalName = name || finalSource;
    const formGroupName = useFormGroupContext();
    const formGroups = useFormGroups();
    const record = useRecordContext();
    // @ts-ignore
    const parse = useEvent(parseProp);
    const defaultId = useId();

    if (!finalName && process.env.NODE_ENV === 'development') {
        console.warn(
            'Input components require either a source or a name prop.'
        );
    }

    useEffect(() => {
        if (!formGroups || formGroupName == null) {
            return;
        }

        formGroups.registerField(finalSource, formGroupName);

        return () => {
            formGroups.unregisterField(finalSource, formGroupName);
        };
    }, [formGroups, formGroupName, finalSource]);

    const sanitizedValidate = Array.isArray(validate)
        ? composeValidators(validate)

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Add the source prop matching the record field, e.g. <TextInput source="name" />.
  2. Pass name if the input is not bound to a record field but must register with the form.
  3. Fix data-driven field lists so every item includes a source before mapping to input components.

Example fix

// before
<TextInput label="Title" validate={required()} />
// after
<TextInput source="title" label="Title" validate={required()} />
Defensive patterns

Strategy: type-guard

Validate before calling

const renderField = (f) => {
  if (typeof f.source !== 'string' || f.source.length === 0) {
    throw new Error(`Input component requires a source; got ${JSON.stringify(f)}`);
  }
  return <TextInput source={f.source} />;
};

Type guard

const hasSource = (props) => typeof props?.source === 'string' && props.source.length > 0;
if (!hasSource(fieldProps) && typeof fieldProps?.name !== 'string') throw new Error('Field needs source or name');

Prevention

When it happens

Trigger: Rendering <TextInput />, <NumberInput />, or any input built on useInput without a source prop (and without name), e.g. <TextInput /> or <TextInput label="Name" />.

Common situations: Creating a purely presentational input; forgetting source after renaming a field; dynamically building inputs from config where a field entry lacks a source key; typos like sources.

Related errors


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