{"record":{"id":"c9b9dd148a0ff1fe","repo":"mastra-ai/mastra","slug":"unsupported-plugin-entry-extension-path-extname","errorCode":null,"errorMessage":"Unsupported plugin entry extension \"${path.extname(entryPath)}\". V1 plugins must use .ts entries.","messagePattern":"Unsupported plugin entry extension \"(.+?)\"\\. V1 plugins must use \\.ts entries\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/plugins/loader.ts","lineNumber":155,"sourceCode":"}\n\nexport function isInsideDirectory(targetPath: string, root: string): boolean {\n  const resolvedTarget = path.resolve(targetPath);\n  const resolvedRoot = path.resolve(root);\n  return resolvedTarget === resolvedRoot || resolvedTarget.startsWith(resolvedRoot + path.sep);\n}\n\nfunction resolveExistingAssetDirs(pluginRoot: string, dirname: 'skills' | 'commands'): string[] {\n  const dir = path.join(pluginRoot, dirname);\n  try {\n    return fs.statSync(dir).isDirectory() ? [dir] : [];\n  } catch {\n    return [];\n  }\n}\n\nasync function importPluginModule(entryPath: string): Promise<MastraCodePlugin> {\n  if (path.extname(entryPath) !== '.ts') {\n    throw new Error(\n      `Unsupported plugin entry extension \"${path.extname(entryPath)}\". V1 plugins must use .ts entries.`,\n    );\n  }\n\n  const url = pathToFileURL(entryPath);\n  const stat = fs.statSync(entryPath, { bigint: true });\n  url.searchParams.set('mtimeNs', stat.mtimeNs.toString());\n  url.searchParams.set('size', stat.size.toString());\n  const mod = (await import(url.href)) as { default?: unknown; plugin?: unknown };\n  return validatePluginExport(mod.default ?? mod.plugin);\n}\n\nfunction validatePluginExport(value: unknown): MastraCodePlugin {\n  if (!value || typeof value !== 'object') {\n    throw new Error('Plugin module must export a plugin object as default or named \"plugin\" export');\n  }\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/plugins/loader.ts#L137-L173","documentation":"importPluginModule only accepts .ts entry files in V1: the SDK relies on its TS-aware import pipeline (with mtime/size cache-busting) which is wired for TypeScript entries. Any other extension (.js, .mjs, .cjs, .json) is rejected before import.","triggerScenarios":"record.entry pointing at 'dist/plugin.js' or 'index.mjs' (e.g. after building the plugin or porting to JS); a JSON entry; a plugin package that ships only compiled JS.","commonSituations":"Migrating an existing JS plugin package into mastracode; pointing the entry at a build output directory out of habit from npm-package conventions; typos giving the file a wrong extension.","solutions":["Point record.entry at the plugin's TypeScript source file, e.g. 'src/index.ts'.","Rename the entry to .ts and convert the module to TypeScript (the loader imports TS directly).","Update the stale plugins.json entry if it still references an old .js build output."],"exampleFix":"// before (plugins.json)\n{ \"id\": \"widgets\", \"entry\": \"dist/index.js\", ... }\n// after\n{ \"id\": \"widgets\", \"entry\": \"src/index.ts\", ... }","handlingStrategy":"validation","validationCode":"import path from 'node:path';\nfunction isTsEntry(entry: string): boolean {\n  return path.extname(entry) === '.ts';\n}\nif (!isTsEntry(record.entry)) throw new Error(`V1 plugins require a .ts entry, got \"${record.entry}\"`);","typeGuard":null,"tryCatchPattern":"const loaded = await loadPluginRecord(record, options);\nif (loaded.status === 'load failed' && loaded.error?.includes('Unsupported plugin entry extension')) {\n  console.error(`Point record.entry at the .ts source (e.g. src/index.ts), not a JS build output.`);\n}","preventionTips":["Set record.entry to the TypeScript source file, not dist/*.js output.","Convert JS plugins to .ts entry modules before installing.","Validate entry extension === '.ts' when generating registry records."],"tags":["plugin-loading","typescript","entry-point","validation"],"backgroundTag":"unsupported-entry-extension","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}