{"record":{"id":"e012a2e48dd6ca53","repo":"laurent22/joplin","slug":"this-plugin-name-cannot-be-converted-to-a-package","errorCode":null,"errorMessage":"This plugin name cannot be converted to a package name: ${pluginName}","messagePattern":"This plugin name cannot be converted to a package name: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/generator-joplin/generators/app/utils.js","lineNumber":64,"sourceCode":"\treturn `${output.filter((item, pos) => {\n\t\tif (!item) return true; // Leave blank lines\n\t\treturn output.indexOf(item) === pos;\n\t}).join('\\n').trim()}\\n`;\n}\n\nfunction packageNameFromPluginName(pluginName) {\n\tlet output = pluginName;\n\n\t// Replace all special characters with '-'\n\toutput = output.replace(/[*+~.()'\"!:@[\\]]/g, '-');\n\n\t// Slugify to replace non-alphabetical characters by letters\n\toutput = slugify(output, { lower: true });\n\n\t// Trim any remaining \"-\" from beginning of string\n\toutput = output.replace(/^[-]+/, '');\n\n\tif (!output) throw new Error(`This plugin name cannot be converted to a package name: ${pluginName}`);\n\n\t// Add prefix\n\toutput = `joplin-plugin-${output}`;\n\n\t// Package name is limited to 214 characters\n\toutput = output.substr(0, 214);\n\n\t// Trim any remaining \"-\" from end of string\n\toutput = output.replace(/[-]+$/, '');\n\n\treturn output;\n}\n\nmodule.exports = { mergePackageKey, mergeIgnoreFile, packageNameFromPluginName };\n","sourceCodeStart":46,"sourceCodeEnd":79,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/generator-joplin/generators/app/utils.js#L46-L79","documentation":"Thrown by packageNameFromPluginName() in generator-joplin utils.js. The plugin name is run through a special-character replace and slugify; if the result is an empty string, the name cannot become a valid npm package name and the generator aborts. The prefix `joplin-plugin-` is added only after this check, so a fully-empty slug never reaches it.","triggerScenarios":"User runs yo joplin (or the generator programmatically) and enters a plugin name consisting entirely of characters that slugify strips — e.g. only symbols, only emoji, only CJK that slugify removes, or only whitespace.","commonSituations":"Plugin name is pure punctuation or a single emoji; name is empty; name uses a script slugify does not transliterate.","solutions":["Re-run the generator and enter a plugin name containing at least one ASCII letter or number (e.g. \"My Cool Plugin\").","Avoid names made only of symbols, emoji, or whitespace.","If a non-Latin name is desired, append a transliterated ASCII portion so the slug is non-empty."],"exampleFix":"# before\n? Plugin name: ✨✨✨\n# after\n? Plugin name: Star Notes","handlingStrategy":"validation","validationCode":"// Before calling the generator, sanity-check the proposed name slugifies to non-empty.\nconst slugify = require('slugify');\nconst slugified = slugify(pluginName.replace(/[*+~.()'\"!:@[\\]]/g, '-'), { lower: true }).replace(/^-+/, '');\nif (!slugified) throw new Error('Plugin name has no usable characters for a package name');","typeGuard":"const isUsablePluginName = (name) => !!slugify(name.replace(/[*+~.()'\"!:@[\\]]/g, '-'), { lower: true }).replace(/^-+/, '');","tryCatchPattern":"try { packageNameFromPluginName(name); }\ncatch (e) { if (/cannot be converted to a package name/.test(e.message)) { /* ask for a new name */ } else throw e; }","preventionTips":["When scaffolding interactively, validate the name live and reject emoji/punctuation-only input.","Suggest an ASCII fallback for non-Latin names so the slug is never empty."],"tags":["generator-joplin","package-naming","scaffold"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}