{"record":{"id":"236ee5a8ecbb3c40","repo":"paperclipai/paperclip","slug":"invalid-template-template-expected-one-of","errorCode":null,"errorMessage":"Invalid template '${template}'. Expected one of: ${VALID_TEMPLATES.join(\", \")}","messagePattern":"Invalid template '(.+?)'\\. Expected one of: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/create-paperclip-plugin/src/index.ts","lineNumber":126,"sourceCode":"\n  const tarballPath = path.join(sdkBundleDir, tarballFileName);\n  if (!fs.existsSync(tarballPath)) {\n    throw new Error(`Packed tarball was not created at ${tarballPath}`);\n  }\n\n  return tarballPath;\n}\n\n/**\n * Generate a complete Paperclip plugin starter project.\n *\n * Output includes manifest/worker/UI entries, SDK harness tests, bundler presets,\n * and a local dev server script for hot-reload workflow.\n */\nexport function scaffoldPluginProject(options: ScaffoldPluginOptions): string {\n  const template = options.template ?? \"default\";\n  if (!VALID_TEMPLATES.includes(template)) {\n    throw new Error(`Invalid template '${template}'. Expected one of: ${VALID_TEMPLATES.join(\", \")}`);\n  }\n\n  if (!isValidPluginName(options.pluginName)) {\n    throw new Error(\"Invalid plugin name. Must be lowercase and may include scope, dots, underscores, or hyphens.\");\n  }\n\n  if (options.category && !VALID_CATEGORIES.has(options.category)) {\n    throw new Error(`Invalid category '${options.category}'. Expected one of: ${[...VALID_CATEGORIES].join(\", \")}`);\n  }\n\n  const outputDir = path.resolve(options.outputDir);\n  if (fs.existsSync(outputDir)) {\n    throw new Error(`Directory already exists: ${outputDir}`);\n  }\n\n  const displayName = options.displayName ?? makeDisplayName(options.pluginName);\n  const description = options.description ?? \"A Paperclip plugin\";\n  const author = options.author ?? \"Plugin Author\";","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/create-paperclip-plugin/src/index.ts#L108-L144","documentation":"scaffoldPluginProject only accepts template values from the fixed set VALID_TEMPLATES = ['default','connector','workspace','environment'] and rejects anything else with a message listing the allowed values. The check runs before name/category validation and before any filesystem writes.","triggerScenarios":"Calling scaffoldPluginProject with options.template set to a value not in the set (e.g. 'typescript', 'worker', 'react', or a typo like 'conector').","commonSituations":"User passes a template name from a different tool's docs; CLI flag --template was given an unsupported value; outdated docs list a template that was renamed/removed.","solutions":["Use one of: default, connector, workspace, environment.","Omit template entirely to get the 'default' template.","If you need a custom layout, scaffold 'default' and modify the output."],"exampleFix":"// before\nscaffoldPluginProject({ pluginName: 'foo', template: 'typescript' })\n// after\nscaffoldPluginProject({ pluginName: 'foo', template: 'default' })","handlingStrategy":"validation","validationCode":"const VALID_TEMPLATES = ['default','connector','workspace','environment'] as const;\nfunction isTemplate(v: unknown): v is typeof VALID_TEMPLATES[number] {\n  return typeof v === 'string' && (VALID_TEMPLATES as readonly string[]).includes(v);\n}\nconst template = isTemplate(options.template) ? options.template : 'default';","typeGuard":"function isPluginTemplate(v: unknown): v is 'default'|'connector'|'workspace'|'environment' {\n  return v === 'default' || v === 'connector' || v === 'workspace' || v === 'environment';\n}","tryCatchPattern":null,"preventionTips":["Restrict the UI/CLI choices to the four valid templates.","Omit template to use 'default' when unsure.","Keep docs in sync with VALID_TEMPLATES after any rename."],"tags":["input-validation","scaffolding","create-paperclip-plugin"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}