shadcn-ui/ui · error · Error

useFormField should be used within <FormField>

Error message

useFormField should be used within <FormField>

What it means

useFormField reads two contexts: FormFieldContext (set by <FormField>, which wraps react-hook-form's Controller) and FormItemContext (set by <FormItem>). It also calls useFormContext (react-hook-form) and getFieldState. If FormFieldContext is the default {} (no <FormField> ancestor), fieldContext is truthy-but-empty; the explicit `if (!fieldContext)` then catches the case where it is genuinely absent and throws, because formItemId/name/fieldState cannot be computed without a registered field.

Source

Thrown at apps/v4/registry/new-york-v4/ui/form.tsx:53

>({
  ...props
}: ControllerProps<TFieldValues, TName>) => {
  return (
    <FormFieldContext.Provider value={{ name: props.name }}>
      <Controller {...props} />
    </FormFieldContext.Provider>
  )
}

const useFormField = () => {
  const fieldContext = React.useContext(FormFieldContext)
  const itemContext = React.useContext(FormItemContext)
  const { getFieldState } = useFormContext()
  const formState = useFormState({ name: fieldContext.name })
  const fieldState = getFieldState(fieldContext.name, formState)

  if (!fieldContext) {
    throw new Error("useFormField should be used within <FormField>")
  }

  const { id } = itemContext

  return {
    id,
    name: fieldContext.name,
    formItemId: `${id}-form-item`,
    formDescriptionId: `${id}-form-item-description`,
    formMessageId: `${id}-form-item-message`,
    ...fieldState,
  }
}

type FormItemContextValue = {
  id: string
}

View on GitHub (pinned to efac598707)

Solutions

  1. Wrap each field group in <FormField name=... render=...> so FormFieldContext is populated.
  2. Ensure the whole form is inside react-hook-form's <Form> (useFormContext needs it).
  3. Keep <FormLabel>/<FormControl>/<FormDescription>/<FormMessage> as descendants of <FormItem> within <FormField>.

Example fix

// before
<FormLabel>Email</FormLabel>
<Input />

// after
<FormField
  name="email"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Email</FormLabel>
      <FormControl><Input {...field} /></FormControl>
      <FormMessage />
    </FormItem>
  )}
/>
Defensive patterns

Strategy: validation

Validate before calling

function useOptionalFormField() {
  const field = React.useContext(FormFieldContext)
  if (!field?.name) return null
  return useFormField() // safe now
}

Type guard

// react-hook-form's Controller populates FormFieldContext only inside <FormField>
function useHasFormField(): boolean {
  return Boolean(React.useContext(FormFieldContext)?.name)
}

Prevention

When it happens

Trigger: Using <FormLabel>, <FormControl>, <FormDescription>, or <FormMessage> outside of a <FormField>; nesting them in a sibling instead of a child of <FormField>; rendering form controls under a plain <form> without react-hook-form's <Form>.

Common situations: Copy-pasting <FormLabel> into a non-form layout; refactoring a field and dropping the <FormField> wrapper; using these components with a different form library.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/9da33a70424fcaff. Report an issue: GitHub.