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

  1. Add try/catch inside onSubmit; on failure call setErrors or setFieldError instead of letting it reject.
  2. Always use `finally { setSubmitting(false) }` so submit state resets even on failure.
  3. 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

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


AI-assisted analysis of jaredpalmer/formik@91475adbf3 (2026-08-27). Data as JSON: /api/errors/242479ab1180bfb2. Report an issue: GitHub.