denoland/deno · error · Error
Linter plugin ${plugin.name} has already been registered
Error message
Linter plugin ${plugin.name} has already been registered What it means
Thrown by installPlugin() in cli/js/40_lint.js when a plugin with the same `name` was already registered in this linter instance (state.installedPlugins). Rule ids are namespaced as `pluginName/ruleName`, so a second plugin with the same name would collide with the first. Unlike the shape errors, this message carries no specifier prefix.
Source
Thrown at cli/js/40_lint.js:507
throw new Error(
`${prefix}Linter plugin name must only contain lowercase letters (a-z) or hyphens (-).`,
);
}
if (plugin.name.startsWith("-") || plugin.name.endsWith("-")) {
throw new Error(
`${prefix}Linter plugin name must start and end with a lowercase letter.`,
);
}
if (plugin.name.includes("--")) {
throw new Error(
`${prefix}Linter plugin name must not have consequtive hyphens.`,
);
}
if (typeof plugin.rules !== "object") {
throw new Error(`${prefix}Linter plugin rules must be an object`);
}
if (state.installedPlugins.has(plugin.name)) {
throw new Error(`Linter plugin ${plugin.name} has already been registered`);
}
state.plugins.push(plugin);
state.installedPlugins.add(plugin.name);
return {
name: plugin.name,
ruleNames: Object.keys(plugin.rules),
};
}
/**
* @param {AstContext} ctx
* @param {number} idx
* @returns {FacadeNode | null}
*/
function getNode(ctx, idx) {
if (idx === AST_IDX_INVALID) return null;
const cached = ctx.nodes.get(idx);View on GitHub (pinned to 89f33cbef2)
Solutions
- Remove the duplicate entry from `lint.plugins` so each plugin name is registered once
- If two distinct plugins share a name, rename one of them to a unique lowercase name
- If you re-export plugins through a barrel module, make sure the barrel is not listed alongside its targets
Example fix
// deno.json before
{
"lint": {
"plugins": ["jsr:@corp/lint", "./lint/index.ts"]
}
}
// deno.json after
{
"lint": {
"plugins": ["jsr:@corp/lint"]
}
} Defensive patterns
Strategy: validation
Validate before calling
const seen = new Set();
for (const p of plugins) {
if (seen.has(p.name)) {
throw new Error(`duplicate lint plugin name: '${p.name}' listed twice`);
}
seen.add(p.name);
} Type guard
function hasUniqueNames(plugins) {
const names = plugins.map((p) => p.name);
return new Set(names).size === names.length;
} Prevention
- Keep `lint.plugins` in deno.json as a flat, deduplicated list — avoid barrels that re-export other listed plugins
- Give every plugin a name tied to its package identity so two teams cannot collide accidentally
When it happens
Trigger: Listing the same plugin twice in `lint.plugins` in deno.json (directly or via two re-exporting modules); shipping two different plugins that both declare name: "recommended"; importing a plugin and also bundling a local copy of it.
Common situations: A config that loads a plugin both from jsr/npm and from a local path; a monorepo where two teams wrote plugins with the same generic name ("lint", "helpers"); stale duplicate entries after refactoring the plugin list.
Related errors
- ${prefix}Linter plugin name must only contain lowercase lett
- ${prefix}Linter plugin name must start and end with a lowerc
- ${prefix}Linter plugin name must not have consequtive hyphen
- ${prefix}Linter plugin rules must be an object
- Visitor "${name}" of plugin "${id}" errored
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/e532b2d8236595a9.
Report an issue: GitHub.