jestjs/jest · error · ValidationError
Watch plugin configuration error: ${error}
Error message
Watch plugin configuration error:
${error} What it means
Thrown as a ValidationError when two watch plugins attempt to register the same key, or when a plugin tries to register a key that is reserved internally by Jest. The conflict is detected during key registration in `determineWatchPlugins`/`updateKeypressHandler` and names both conflicting plugins or the reserved key name.
Source
Thrown at packages/jest-core/src/watch.ts:514
Watch plugin ${chalk.bold.red(
getPluginIdentifier(plugin),
)} attempted to register key ${chalk.bold.red(`<${key}>`)},
that is reserved internally for ${chalk.bold.red(
conflictor.forbiddenOverwriteMessage,
)}.
Please change the configuration key for this plugin.`.trim();
} else {
const plugins = [conflictor.plugin, plugin]
.map(p => chalk.bold.red(getPluginIdentifier(p)))
.join(' and ');
error = `
Watch plugins ${plugins} both attempted to register key ${chalk.bold.red(
`<${key}>`,
)}.
Please change the key configuration for one of the conflicting plugins to avoid overlap.`.trim();
}
throw new ValidationError('Watch plugin configuration error', error);
};
const getPluginIdentifier = (plugin: WatchPlugin) =>
// This breaks as `displayName` is not defined as a static, but since
// WatchPlugin is an interface, and it is my understanding interface
// static fields are not definable anymore, no idea how to circumvent
// this :-(
// @ts-expect-error: leave `displayName` be.
plugin.constructor.displayName || plugin.constructor.name;
const getPluginKey = (
plugin: WatchPlugin,
globalConfig: Config.GlobalConfig,
) => {
if (typeof plugin.getUsageInfo === 'function') {
return (plugin.getUsageInfo(globalConfig) || {key: null}).key;
}
View on GitHub (pinned to 8e6d128e4a)
Solutions
- Read the error message — it names both conflicting plugins and the disputed key.
- Change the key configuration for one of the plugins in your jest.config `watchPlugins` array (pass a different key as the plugin's config option).
- If a plugin attempts a reserved key, the message names the reserved purpose — pick a non-reserved key.
- Remove one of the conflicting watch plugins if both are not needed.
Example fix
// before: jest.config.js — both plugins use 'p'
module.exports = {
watchPlugins: [
['jest-watch-typeahead/filename', { key: 'p' }],
['jest-watch-select-projects', { key: 'p' }],
],
};
// after: give each a unique key
module.exports = {
watchPlugins: [
['jest-watch-typeahead/filename', { key: 'f' }],
['jest-watch-select-projects', { key: 'p' }],
],
}; Defensive patterns
Strategy: validation
Validate before calling
// Before Jest starts, check watch plugin keys for collisions
function validateWatchPluginKeys(plugins) {
const keys = new Map();
for (const [name, opts] of plugins) {
const key = opts?.key;
if (!key) continue;
if (keys.has(key)) {
throw new Error(`Key '${key}' is used by both ${keys.get(key)} and ${name}`);
}
keys.set(key, name);
}
} Prevention
- Review the default key of each watch plugin before adding multiple to the config.
- Explicitly assign unique keys to each plugin in the watchPlugins config array.
- Avoid using reserved Jest keys (q, u, f, t, o, i, p, w, a, e) for custom plugins.
When it happens
Trigger: Configuring two `watchPlugins` entries in jest.config that both claim the same key (e.g. both return `{key: 'f'}` from `getUsageInfo`), or a custom plugin returning a key like `q` or `u` that Jest reserves internally. Also triggered when a plugin sets `overwritable: false` (default) and another plugin tries to use the same key.
Common situations: Installing multiple community watch plugins that overlap on default keys. Writing a custom watch plugin and unknowingly using a key Jest already binds. Upgrading a plugin whose default key changed to collide with another.
Related errors
- Jest: Got error running ${moduleName} - ${modulePath}, reaso
- Shard ${globalConfig.shard.shardIndex}/${globalConfig.shard.
- Failed to start watch mode.
- babel-jest: Babel ignores ${chalk.bold(slash(path.relative(c
- Could not find a "package.json" file in ${rootDir}
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/5d469a7c0c9e41f4.
Report an issue: GitHub.