facebook/react · error · Error
522
522
Error message
Invalid form element. requestFormReset must be passed a form that was rendered by React.
What it means
The isomorphic react-dom package installs a default dispatcher whose requestFormReset entry (ReactDOMSharedInternals.d.r) always throws; a real implementation is swapped in only when a host config loads (the DOM client renderer in ReactFiberConfigDOM, the Fizz DOM server in ReactFizzConfigDOM, or the Flight server dispatcher). The public requestFormReset(form) API re-exported from 'react-dom' delegates to that dispatcher entry, so calling it before any host config has initialized — or in a bundle where none ever will — raises this error (code 522).
Source
Thrown at packages/react-dom/src/ReactDOMSharedInternals.js:28
import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
import type {HostDispatcher} from './shared/ReactDOMTypes';
import noop from 'shared/noop';
// This should line up with NoEventPriority from react-reconciler/src/ReactEventPriorities
// but we can't depend on the react-reconciler from this isomorphic code.
export const NoEventPriority: EventPriority = 0 as any;
type ReactDOMInternals = {
d /* ReactDOMCurrentDispatcher */: HostDispatcher,
p /* currentUpdatePriority */: EventPriority,
findDOMNode:
| null
| ((componentOrElement: component(...props: any)) => null | Element | Text),
};
function requestFormReset(element: HTMLFormElement) {
throw new Error(
'Invalid form element. requestFormReset must be passed a form that was ' +
'rendered by React.',
);
}
const DefaultDispatcher: HostDispatcher = {
f /* flushSyncWork */: noop,
r /* requestFormReset */: requestFormReset,
D /* prefetchDNS */: noop,
C /* preconnect */: noop,
L /* preload */: noop,
m /* preloadModule */: noop,
X /* preinitScript */: noop,
S /* preinitStyle */: noop,
M /* preinitModuleScript */: noop,
};
const Internals: ReactDOMInternals = {View on GitHub (pinned to eafeac097b)
Solutions
- Only call requestFormReset from client code that runs after react-dom/client has initialized — inside a form action or transition
- Run npm ls react react-dom to detect and remove duplicate copies so the dispatcher install is visible to the copy you call
- Pass only <form> elements obtained via React refs on React-rendered markup, never querySelector or createElement results
- If React is not managing the form, use the native form.reset() instead
Example fix
// before (runs during SSR — dispatcher never initialized)
import {requestFormReset} from 'react-dom';
requestFormReset(formRef.current);
// after (runs in a client action)
'use client';
import {requestFormReset} from 'react-dom';
function saveAction() {
requestFormReset(formRef.current);
} Defensive patterns
Strategy: validation
Validate before calling
const canRequestReset =
typeof window !== 'undefined' && // client renderer available
form instanceof window.HTMLFormElement &&
form.isConnected; // a real, mounted form
if (canRequestReset) {
requestFormReset(form);
} else {
form.reset(); // native fallback outside React DOM control
} Type guard
function isClientManagedForm(form: unknown): form is HTMLFormElement {
return typeof window !== 'undefined' && form instanceof window.HTMLFormElement && form.isConnected;
} Try / catch
try {
requestFormReset(form);
} catch (e) {
if (e instanceof Error && e.message.includes('requestFormReset')) {
form.reset(); // dispatcher not initialized or form not React-managed
} else {
throw e;
}
} Prevention
- Call requestFormReset only from client-side form actions or transitions
- Obtain the form through a React ref on a rendered <form>, never querySelector
- Run npm ls react react-dom after dependency changes to catch duplicate dispatcher copies
- Prefer <form action={fn}> auto-reset, which never touches this API
When it happens
Trigger: Calling requestFormReset(form) (exported from 'react-dom'/'react-dom/client' via ReactDOMFormActions) in an environment where only the isomorphic build loaded: SSR-only or RSC code paths with no client renderer, custom renderers reusing shared internals, or duplicate react-dom copies so the dispatcher install (ReactFiberConfigDOM.js:5072) lands in a different instance than the one you call.
Common situations: Server-side modules invoking ReactDOM.requestFormReset; npm dedupe failures producing two react-dom copies; calling it during SSR instead of inside a client-side form action; passing a form built with document.createElement rather than rendered by React.
Related errors
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/9c7ccff68398221c.
Report an issue: GitHub.