Troubleshooting
Debug common adoption problems by symptom. Each item maps directly to a root cause and a minimal correction.
I click submit and nothing happens.
Likely cause: handleSubmit is not wired correctly, submit button type is wrong, or client validation blocked execution.
Quick fix: Use onSubmit={handleSubmit()} and inspect formState.errors after click.
Action is not called even with valid-looking fields.
Likely cause: Client-side schema validation failed before the network request.
Quick fix: Check validationMode and verify each field against the schema.
Server errors are not shown on inputs.
Likely cause: Returned error shape does not match default mapper expectations.
Quick fix: Return { errors: Record<string, string[]> } or implement errorMapper.
Errors show on the wrong field (nested/array forms).
Likely cause: Error keys do not match RHF field paths.
Quick fix: Use RHF paths like address.city and items.0.price in server error keys.
Submit button enables too early and allows double submits.
Likely cause: UI is using isSubmitting instead of isPending.
Quick fix: Disable by formState.isPending for end-to-end submit state.
Old values keep returning in edit forms.
Likely cause: persistKey restored an old draft and overrode defaults.
Quick fix: Scope persistKey per entity and clear persisted drafts on load/success.
optimistic is undefined or has no effect.
Likely cause: Incomplete optimistic setup or UI is rendering confirmed data only.
Quick fix: Provide optimisticKey + optimisticData and render optimistic.data while pending.
File upload fails or file is empty on server.
Likely cause: Using JSON flow for file input instead of FormData action handling.
Quick fix: Use a FormData-based action and validate file type/size server-side.
onError does not fire when the form is invalid.
Likely cause: Invalid client form never reaches action execution.
Quick fix: Use formState.errors for client invalid state; onError handles action failure paths.
Standalone flow expects formAction but it does not exist.
Likely cause: Standalone API signature differs from Next.js adapter.
Quick fix: Use submit in options and trigger with handleSubmit().
60-second checklist
- 1.Confirm package choice: next adapter vs standalone adapter.
- 2.Confirm schema and validationMode match your intended UX.
- 3.Confirm action return shape for field errors.
- 4.Confirm field names and error keys use identical RHF paths.
- 5.Confirm submit buttons are gated by isPending.
- 6.Confirm persistKey scope and clear strategy.
- 7.Confirm optimistic settings and rendering path.
- 8.Confirm file flows use FormData, not JSON.