{"record":{"id":"f083758d206d532f","repo":"mastra-ai/mastra","slug":"plugin-manifest-file-plugin-candidate-id-mus","errorCode":null,"errorMessage":"${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry","messagePattern":"(.+?) plugin (.+?) must include an entry","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/plugins/manifest.ts","lineNumber":77,"sourceCode":"    throw new Error(\n      `${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide an entry path for one of: ${manifest.plugins\n        .map(plugin => `${plugin.id} (${plugin.entry})`)\n        .join(', ')}`,\n    );\n  }\n  return manifest.plugins[0];\n}\n\nfunction validateManifestEntry(entry: unknown, index: number): PluginManifestEntry {\n  if (!entry || typeof entry !== 'object') {\n    throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);\n  }\n  const candidate = entry as { id?: unknown; name?: unknown; entry?: unknown };\n  if (typeof candidate.id !== 'string' || candidate.id.length === 0) {\n    throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);\n  }\n  if (typeof candidate.entry !== 'string' || candidate.entry.length === 0) {\n    throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);\n  }\n  if (candidate.name !== undefined && typeof candidate.name !== 'string') {\n    throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);\n  }\n  return {\n    id: candidate.id,\n    entry: candidate.entry,\n    ...(candidate.name ? { name: candidate.name } : {}),\n  };\n}\n","sourceCodeStart":59,"sourceCodeEnd":88,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/plugins/manifest.ts#L59-L88","documentation":"Thrown by validateManifestEntry when a manifest entry has a valid `id` but its `entry` field is missing, not a string, or an empty string. The `entry` field points to the plugin's module path and is required for the plugin to be loaded; without it there is nothing to import, so the loader rejects the entry.","triggerScenarios":"loadPluginManifest reading a plugins.json entry like {\"id\":\"my-plugin\"} or {\"id\":\"my-plugin\",\"entry\":\"\"}; upsertPluginManifestEntry being called with an object lacking `entry`; a build step stripping the entry field.","commonSituations":"Creating a new manifest entry by copying only the id/name fields and forgetting entry; a template expansion that fails to substitute the entry path, leaving it empty; deleting the entry while reorganizing the project layout.","solutions":["Add a non-empty string `entry` to the manifest entry with the given id, pointing at the plugin's compiled module (e.g. \"./dist/index.js\").","Confirm the referenced file actually exists relative to the manifest/package root and will exist at load time.","If entry was lost during a build/generation step, fix the template or script so it always emits the entry path.","Re-run the loader to validate."],"exampleFix":"// before\n{ \"id\": \"my-plugin\", \"name\": \"My Plugin\" }\n// after\n{ \"id\": \"my-plugin\", \"name\": \"My Plugin\", \"entry\": \"./dist/index.js\" }","handlingStrategy":"validation","validationCode":"const entries = JSON.parse(fs.readFileSync('plugins.json', 'utf8'));\nfor (const e of entries) {\n  if (typeof e?.entry !== 'string' || e.entry.length === 0) {\n    throw new Error(`plugin \"${e?.id}\" is missing its entry path; add it before loading`);\n  }\n  if (!fs.existsSync(path.join(pkgRoot, e.entry))) {\n    throw new Error(`entry path does not exist: ${e.entry}`);\n  }\n}","typeGuard":"function hasEntry(entry: unknown): entry is { id: string; entry: string } {\n  return typeof entry === 'object' && entry !== null &&\n    typeof (entry as { entry?: unknown }).entry === 'string' &&\n    (entry as { entry: string }).entry.length > 0;\n}","tryCatchPattern":"try {\n  loadPluginManifest(dir);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('must include an entry')) {\n    console.error(`Fix the manifest: ${err.message}`);\n  } else throw err;\n}","preventionTips":["Generate manifest entries from a template that always fills in entry.","Assert the built entry file exists (e.g. dist/index.js) as part of your build script.","Keep build output paths stable so the entry path does not silently change."],"tags":["plugin-manifest","validation","configuration"],"backgroundTag":"manifest-entry-missing-required-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}