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 be

View on GitHub (pinned to f131c034ad)

Solutions

  1. 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).
  2. Verify the resolved entry: `node -e "import('<pkg>').then(m => console.log('default' in m, Object.keys(m)))"` and confirm `default` is present.
  3. 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.
  4. 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

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


AI-assisted analysis of eslint/eslint@f131c034ad (2026-08-03). Data as JSON: /data/errors/07f6ad78146c277f.json. Report an issue: GitHub.