facebook/react · error · Error
97
97
Error message
EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `${pluginName}` does not. What it means
Every legacy event plugin must implement extractEvents, the hook the dispatch loop calls to build synthetic events for a top-level event; the registry throws at injection time when a module lacks it. The message names the offending plugin so the bad module is easy to spot.
Source
Thrown at packages/react-native-renderer/src/legacy-events/EventPluginRegistry.js:60
}
for (const pluginName in namesToPlugins) {
const pluginModule = namesToPlugins[pluginName];
// $FlowFixMe[incompatible-use] found when upgrading Flow
const pluginIndex = eventPluginOrder.indexOf(pluginName);
if (pluginIndex <= -1) {
throw new Error(
'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
`the plugin ordering, \`${pluginName}\`.`,
);
}
if (plugins[pluginIndex]) {
continue;
}
if (!pluginModule.extractEvents) {
throw new Error(
'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
`method, but \`${pluginName}\` does not.`,
);
}
plugins[pluginIndex] = pluginModule;
const publishedEvents = pluginModule.eventTypes;
for (const eventName in publishedEvents) {
if (
!publishEventForPlugin(
publishedEvents[eventName],
pluginModule,
eventName,
)
) {
throw new Error(
`EventPluginRegistry: Failed to publish event \`${eventName}\` for plugin \`${pluginName}\`.`,
);View on GitHub (pinned to eafeac097b)
Solutions
- Implement extractEvents on the plugin module (returning null for events it wants to ignore).
- Remove the module from injection if it is not meant to be a dispatch plugin.
- Verify the object actually reaching the registry has the right shape (not a module namespace or the module's default).
Example fix
// before
const MyPlugin = {eventTypes: {/* ... */}};
// after
const MyPlugin = {
eventTypes: {/* ... */},
extractEvents(topLevelType, targetInst, nativeEvent, eventTarget) {
return null;
},
}; Defensive patterns
Strategy: type-guard
Type guard
const isLegacyPluginModule = module =>
module != null && typeof module.extractEvents === 'function';
const pluginsToInject = {MyPlugin};
for (const [name, module] of Object.entries(pluginsToInject)) {
if (!isLegacyPluginModule(module)) {
throw new Error(`Plugin '${name}' must implement extractEvents`);
}
}
injectEventPluginsByName(pluginsToInject); Prevention
- Implement extractEvents on every plugin module before injecting (return null to ignore).
- Confirm the injected object is the plugin itself, not a module namespace or default export mixup.
- Mirror an existing plugin's shape when porting from another event system.
When it happens
Trigger: Injecting a plugin module without an extractEvents method (or with it renamed/mistyped) via injectEventPluginsByName - for example a partial port or a module namespace/default-export mixup that yields the wrong object shape.
Common situations: Porting plugins from newer event systems that don't use extractEvents; incomplete plugin implementations; broken transpilation or module resolution of plugin files.
Related errors
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/abe7907758f50a5d.
Report an issue: GitHub.