denoland/deno · error · Error
${prefix}Linter plugin name must only contain lowercase lett
Error message
${prefix}Linter plugin name must only contain lowercase letters (a-z) or hyphens (-). What it means
Thrown by installPlugin() in cli/js/40_lint.js when a Deno lint plugin's `name` fails the /^[a-z-]+$/ check. Plugin names are used to build rule ids like `plugin-name/rule-name`, so they must be strictly lowercase ASCII letters and single hyphens; the regex also rejects an empty name. When the plugin came from a `lint.plugins` entry in the config, the message is prefixed with the specifier so you know which file is at fault.
Source
Thrown at cli/js/40_lint.js:489
/**
* @param {Deno.lint.Plugin} plugin
* @param {string} [specifier] The specifier the plugin was loaded from, if any.
*/
function installPlugin(plugin, specifier) {
// When the plugin was loaded from a specifier (i.e. `lint.plugins` in the
// config), prefix validation errors with it so the user knows which plugin
// is misbehaving instead of getting an anonymous error.
const prefix = typeof specifier === "string"
? `Failed to load lint plugin '${specifier}': `
: "";
if (typeof plugin !== "object") {
throw new Error(`${prefix}Linter plugin must be an object`);
}
if (typeof plugin.name !== "string") {
throw new Error(`${prefix}Linter plugin name must be a string`);
}
if (!/^[a-z-]+$/.test(plugin.name)) {
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`);View on GitHub (pinned to 89f33cbef2)
Solutions
- Rename the plugin to lowercase letters and single hyphens, e.g. "my-plugin"
- If the name came from a config-loaded plugin, check the 'Failed to load lint plugin \'<specifier>\':' prefix to find the offending file
- Keep the name non-empty, starting/ending with a letter, with no consecutive hyphens (the following checks also apply)
Example fix
// before
export default {
name: "myLintPlugin",
rules: { /* ... */ },
};
// after
export default {
name: "my-lint-plugin",
rules: { /* ... */ },
}; Defensive patterns
Strategy: validation
Validate before calling
const NAME_RE = /^[a-z]+(?:-[a-z]+)*$/; // charset + edges + no doubles
function assertValidPluginName(name) {
if (typeof name !== "string") throw new TypeError("plugin.name must be a string");
if (!NAME_RE.test(name)) {
throw new TypeError(
`invalid plugin name '${name}': use lowercase letters and single inner hyphens`,
);
}
}
// run before registering / shipping the plugin
assertValidPluginName(plugin.name); Type guard
function isValidLintPluginName(name) {
return typeof name === "string" && /^[a-z]+(?:-[a-z]+)*$/.test(name);
} Prevention
- Derive plugin names from the package name early and never hand-edit them per rule
- Add a unit test that validates your plugin object's shape (name + rules) so mis-edits fail in your CI, not in users' lint runs
- Run `deno lint` once on a scratch file as a smoke test after any plugin edit
When it happens
Trigger: A plugin object whose `name` contains uppercase letters ("myPlugin"), digits ("plugin2"), underscores ("my_plugin"), whitespace, non-ASCII characters, or is the empty string "". Reached via `lint.plugins` in deno.json or programmatic plugin installation before any linting runs.
Common situations: Porting an ESLint plugin to a Deno lint plugin and keeping a camelCase or snake_case name; copying a plugin file and renaming it with a version suffix like "my-plugin-2"; forgetting the name field and defaulting it to "".
Related errors
- ${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
- Linter plugin ${plugin.name} has already been registered
- Unexpected 'name' field in options, bench name is already pr
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/bdb58f451906a0e6.
Report an issue: GitHub.