jaredpalmer/formik · warning
Warning: An unhandled error was caught from submitForm()
Error message
Warning: An unhandled error was caught from submitForm()
What it means
Your `onSubmit` (or the submission pipeline) returned/returned a Promise that rejected, and nothing handled it — Formik's internal `handleSubmit` attaches a `.catch` that only logs. This almost always means `onSubmit` threw unexpectedly (not a normal validation flow), or you use `setSubmitting(false)` incorrectly after an awaited failure.
Source
Thrown at packages/formik/src/Formik.tsx:837
// a common gotcha in forms with both reset and submit buttons,
// where the dev forgets to add type="button" to the reset button.
if (__DEV__ && typeof document !== 'undefined') {
// Safely get the active element (works with IE)
const activeElement = getActiveElement();
if (
activeElement !== null &&
activeElement instanceof HTMLButtonElement
) {
invariant(
activeElement.attributes &&
activeElement.attributes.getNamedItem('type'),
'You submitted a Formik form using a button with an unspecified `type` attribute. Most browsers default button elements to `type="submit"`. If this is not a submit button, please add `type="button"`.'
);
}
}
submitForm().catch(reason => {
console.warn(
`Warning: An unhandled error was caught from submitForm()`,
reason
);
});
}
);
const imperativeMethods: FormikHelpers<Values> = {
resetForm,
validateForm: validateFormWithHighPriority,
validateField,
setErrors,
setFieldError,
setFieldTouched,
setFieldValue,
setStatus,
setSubmitting,
setTouched,View on GitHub (pinned to 91475adbf3)
Solutions
- Add try/catch inside onSubmit; on failure call setErrors or setFieldError instead of letting it reject.
- Always use `finally { setSubmitting(false) }` so submit state resets even on failure.
- If you call submitForm() yourself, attach `.catch(errors => ...)` to handle submission errors explicitly.
Example fix
// before
onSubmit: async values => {
await api.save(values); // rejection => unhandled
setSubmitting(false);
}
// after
onSubmit: async (values, { setErrors, setSubmitting }) => {
try {
await api.save(values);
} catch (e) {
setErrors({ submit: 'Save failed' });
} finally {
setSubmitting(false);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
onSubmit: async (values, { setErrors, setSubmitting }) => {
try {
await api.save(values);
} catch (e: any) {
setErrors({ submit: e?.message ?? 'Submission failed' });
} finally {
setSubmitting(false);
}
}
// and if calling manually:
formik.submitForm().catch(err => setSubmitError(err)); Prevention
- Never let onSubmit reject; catch and map to setErrors/setFieldError
- Use finally to reset isSubmitting
- Add a global ErrorBoundary for render-time fallout from bad submit state
When it happens
Trigger: `onSubmit` throws synchronously or its async function rejects (network error, undefined access) without an internal try/catch; or code calls `formikProps.submitForm()` without `.catch`. In this specific source, the Formik-rendered submit handler fires `submitForm()` and any rejection lands in this catch.
Common situations: API call inside onSubmit fails (4xx/5xx/network) and is not caught; forgetting try/finally around async submit so setSubmitting(false) never runs; mutation on a response like `res.data.foo` when the request errored.
Related errors
- Warning: An unhandled error was caught during validation in
- Warning: An unhandled error was caught during validation in
- Warning: Formik called \`${handlerName}\`, but you forgot to
AI-assisted analysis of jaredpalmer/formik@91475adbf3 (2026-08-27).
Data as JSON: /api/errors/242479ab1180bfb2.
Report an issue: GitHub.