eslint/eslint · error · Error
"${longName}" cannot be used with the `--plugin` option beca
Error message
"${longName}" cannot be used with the `--plugin` option because its default module does not provide a `default` export What it means
Thrown by loadPlugins() in lib/shared/translate-cli-options.js:45 when a module loaded via the `--plugin` CLI option has no `default` export. ESLint's `--plugin` mechanism requires each plugin package to expose a `default` export (the plugin object); without it ESLint cannot attach the plugin. The check is `if (!("default" in module))`.
Source
Thrown at lib/shared/translate-cli-options.js:45
// Helpers
//------------------------------------------------------------------------------
/**
* Loads plugins with the specified names.
* @param {{ "import": (name: string) => Promise<any> }} importer An object with an `import` method called once for each plugin.
* @param {string[]} pluginNames The names of the plugins to be loaded, with or without the "eslint-plugin-" prefix.
* @returns {Promise<Record<string, Plugin>>} A mapping of plugin short names to implementations.
*/
async function loadPlugins(importer, pluginNames) {
const plugins = {};
await Promise.all(
pluginNames.map(async pluginName => {
const longName = normalizePackageName(pluginName, "eslint-plugin");
const module = await importer.import(longName);
if (!("default" in module)) {
throw new Error(
`"${longName}" cannot be used with the \`--plugin\` option because its default module does not provide a \`default\` export`,
);
}
const shortName = getShorthandName(pluginName, "eslint-plugin");
plugins[shortName] = module.default;
}),
);
return plugins;
}
/**
* Predicate function for whether or not to apply fixes in quiet mode.
* If a message is a warning, do not apply a fix.
* @param {LintMessage} message The lint result.
* @returns {boolean} `true` if the lint message is an error (and thus should beView on GitHub (pinned to f131c034ad)
Solutions
- Ensure the plugin package has `export default <pluginObject>` (ESM) or `module.exports = <pluginObject>` at its entry (the module-importer treats a CJS `module.exports` as the default).
- Verify the resolved entry: `node -e "import('<pkg>').then(m => console.log('default' in m, Object.keys(m)))"` and confirm `default` is present.
- Check the plugin's package.json `main`/`exports` mapping isn't pointing at a non-default-exporting file, and pin/upgrade the plugin to a version compatible with your ESLint major.
- If you only need the plugin in config, load it via the flat config `plugins` map (passing the object) instead of `--plugin`.
Example fix
// before: eslint-plugin-foo/index.js (ESM, missing default)
export const rules = { "my-rule": { meta: {}, create() {} } };
// after
const foo = { rules: { "my-rule": { meta: {}, create() {} } } };
export default foo; Defensive patterns
Strategy: validation
Validate before calling
async function assertPluginHasDefault(specifier) {
const mod = await import(specifier);
if (!("default" in mod)) {
throw new Error(`${specifier} has no default export; cannot use with --plugin`);
}
return mod.default;
} Type guard
/** @param {unknown} m */
function hasDefaultExport(m) {
return typeof m === "object" && m !== null && "default" in m;
} Try / catch
try {
plugins = await loadPlugins(importer, pluginNames);
} catch (err) {
if (/does not provide a `default` export/.test(err.message)) {
// switch from --plugin to explicit flat-config plugins map
} else throw err;
} Prevention
- Author plugins with a single `export default pluginObject` (ESM) or `module.exports = pluginObject` (CJS).
- Before releasing a plugin, run `node -e "import('my-plugin').then(m=>console.log('default' in m))"`.
- Pin plugin versions known to be compatible with your ESLint major.
When it happens
Trigger: Running `eslint --plugin my-plugin` where the resolved package's entry point exports only named exports (e.g. `module.exports.rules = {...}` via CommonJS but not interpreted as default), or an ESM package that forgot `export default`. Also triggered by a plugin package whose `main`/`exports` field points at a sub-file without a default export.
Common situations: Upgrading a plugin to ESM and forgetting `export default`; pointing `--plugin` at a local path that re-exports named symbols; a plugin authored for an older ESLint that returned the plugin object from `module.exports` directly but is now loaded through an ESM-aware importer that sees no `default`; version mismatch between ESLint and the plugin.
Related errors
- Option concurrency: '${concurrency}' is not a positive integ
- Cannot redefine plugin "${key}".
- This appears to be in eslintrc format (array of strings) rat
- Key "${key}": Expected an object.
- Formatter must be a function, but got a ${typeof formatter}.
AI-assisted analysis of eslint/eslint@f131c034ad (2026-08-03).
Data as JSON: /data/errors/07f6ad78146c277f.json.
Report an issue: GitHub.