{"record":{"id":"ad386a8fdbfebe1c","repo":"mastra-ai/mastra","slug":"plugin-manifest-file-plugin-candidate-id-nam","errorCode":null,"errorMessage":"${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string","messagePattern":"(.+?) plugin (.+?) name must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/plugins/manifest.ts","lineNumber":80,"sourceCode":"        .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":62,"sourceCodeEnd":88,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/plugins/manifest.ts#L62-L88","documentation":"Thrown by validateManifestEntry when a manifest entry supplies a `name` that is not a string. The `name` field is optional (it is only spread into the result when truthy), but if present it must be a string, since it is used as a human-readable display name. The library fails fast instead of coercing or ignoring bad values.","triggerScenarios":"loadPluginManifest encountering an entry like {\"id\":\"x\",\"entry\":\"./dist/index.js\",\"name\":123} or name:true; upsertPluginManifestEntry being handed an object with a numeric or null name.","commonSituations":"JSON tooling or a config generator emitting a numeric version-like name (e.g. name: 2); hand-editing and leaving name: null or name: true; importing manifest data from another tool that uses a different name type.","solutions":["Change the entry's `name` value to a quoted string (e.g. \"name\": \"My Plugin\").","If no display name is needed, remove the `name` key entirely — it is optional.","Fix any config-generation code that emits non-string names (numbers, booleans, null).","Re-run to confirm the manifest passes validation."],"exampleFix":"// before\n{ \"id\": \"my-plugin\", \"entry\": \"./dist/index.js\", \"name\": 42 }\n// after\n{ \"id\": \"my-plugin\", \"entry\": \"./dist/index.js\", \"name\": \"42\" }","handlingStrategy":"type-guard","validationCode":"const entries = JSON.parse(fs.readFileSync('plugins.json', 'utf8'));\nconst bad = entries.filter(e => 'name' in e && typeof e.name !== 'string');\nif (bad.length) throw new Error(`non-string name in manifest for: ${bad.map(e => e.id).join(', ')}`);","typeGuard":"function hasValidName(entry: { name?: unknown }): entry is { name?: string } {\n  return entry.name === undefined || typeof entry.name === 'string';\n}","tryCatchPattern":"try {\n  loadPluginManifest(dir);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('name must be a string')) {\n    console.error(`Manifest name field has wrong type: ${err.message}`);\n  } else throw err;\n}","preventionTips":["Only include the optional name key when you have a string value (avoid name: null).","Coerce display names to strings at generation time (String(value)).","Validate manifest with a schema (zod/yup) so wrong types are caught before load."],"tags":["plugin-manifest","validation","types"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}