remix-run/react-router · error · Error

Cannot submit element that is not <form>, <button>, or <inpu

Error message

Cannot submit element that is not <form>, <button>, or <input type="submit|image">

What it means

`getFormSubmissionInfo` was passed an `HTMLElement` that is not a `<form>`, `<button>`, or `<input type=submit|image>`. The DOM submit target is of an unsupported type.

Source

Thrown at packages/react-router/lib/dom/dom.ts:340

    // Build a FormData object populated from a form and submitter
    formData = new FormData(form, target);

    // If this browser doesn't support the `FormData(el, submitter)` format,
    // then tack on the submitter value at the end.  This is a lightweight
    // solution that is not 100% spec compliant.  For complete support in older
    // browsers, consider using the `formdata-submitter-polyfill` package
    if (!isFormDataSubmitterSupported()) {
      let { name, type, value } = target;
      if (type === "image") {
        let prefix = name ? `${name}.` : "";
        formData.append(`${prefix}x`, "0");
        formData.append(`${prefix}y`, "0");
      } else if (name) {
        formData.append(name, value);
      }
    }
  } else if (isHtmlElement(target)) {
    throw new Error(
      `Cannot submit element that is not <form>, <button>, or ` +
        `<input type="submit|image">`,
    );
  } else {
    method = defaultMethod;
    action = null;
    encType = defaultEncType;
    body = target;
  }

  // Send body for <Form encType="text/plain" so we encode it into text
  if (formData && encType === "text/plain") {
    body = formData;
    formData = undefined;
  }

  return { action, method: method.toLowerCase(), encType, formData, body };
}

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Pass a supported target: a `<form>`, a `<button type="submit">`, or an `<input type="submit|image">`.
  2. If you have raw values, pass a `FormData` or plain object via the `submit(data, opts)` overload instead of a DOM node.
  3. Type the submit target in your handler so TypeScript rejects unsupported nodes.

Example fix

// before
submit(divRef.current); // <div>

// after
submit(formRef.current); // <form>
Defensive patterns

Strategy: type-guard

Validate before calling

function isSubmitTarget(t: unknown): t is HTMLFormElement | HTMLButtonElement | HTMLInputElement {
  if (t instanceof HTMLFormElement) return true;
  if (t instanceof HTMLButtonElement) return true;
  return t instanceof HTMLInputElement && (t.type === 'submit' || t.type === 'image');
}
if (!isSubmitTarget(node)) throw new Error('Unsupported submit target');

Type guard

function isFormSubmitTarget(t: unknown): t is HTMLFormElement | HTMLButtonElement | HTMLInputElement {
  return (
    t instanceof HTMLFormElement ||
    t instanceof HTMLButtonElement ||
    (t instanceof HTMLInputElement && (t.type === 'submit' || t.type === 'image'))
  );
}

Prevention

When it happens

Trigger: Calling `useSubmit()`/`submit()` with an arbitrary DOM node (a `<div>`, `<a>`, etc.) as the target; passing a submitter element from an event whose `currentTarget` is not one of the supported elements.

Common situations: Programmatic submission where the developer passes `event.currentTarget` from a non-form element; refactoring that switched a `<button>` to a `<div role="button">` without updating the submit call; an `onClick` on a non-submit element calling `submit(element)`.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/bbf5177fd1b19b55. Report an issue: GitHub.