mastra-ai/mastra · error
${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be
Error message
${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string What it means
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.
Source
Thrown at mastracode/sdk/src/plugins/manifest.ts:80
.join(', ')}`,
);
}
return manifest.plugins[0];
}
function validateManifestEntry(entry: unknown, index: number): PluginManifestEntry {
if (!entry || typeof entry !== 'object') {
throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an object`);
}
const candidate = entry as { id?: unknown; name?: unknown; entry?: unknown };
if (typeof candidate.id !== 'string' || candidate.id.length === 0) {
throw new Error(`${PLUGIN_MANIFEST_FILE} plugin at index ${index} must include an id`);
}
if (typeof candidate.entry !== 'string' || candidate.entry.length === 0) {
throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include an entry`);
}
if (candidate.name !== undefined && typeof candidate.name !== 'string') {
throw new Error(`${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} name must be a string`);
}
return {
id: candidate.id,
entry: candidate.entry,
...(candidate.name ? { name: candidate.name } : {}),
};
}
View on GitHub (pinned to 75dd419e61)
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.
Example fix
// before
{ "id": "my-plugin", "entry": "./dist/index.js", "name": 42 }
// after
{ "id": "my-plugin", "entry": "./dist/index.js", "name": "42" } Defensive patterns
Strategy: type-guard
Validate before calling
const entries = JSON.parse(fs.readFileSync('plugins.json', 'utf8'));
const bad = entries.filter(e => 'name' in e && typeof e.name !== 'string');
if (bad.length) throw new Error(`non-string name in manifest for: ${bad.map(e => e.id).join(', ')}`); Type guard
function hasValidName(entry: { name?: unknown }): entry is { name?: string } {
return entry.name === undefined || typeof entry.name === 'string';
} Try / catch
try {
loadPluginManifest(dir);
} catch (err) {
if (err instanceof Error && err.message.includes('name must be a string')) {
console.error(`Manifest name field has wrong type: ${err.message}`);
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Worker resourceLimits.${name} must be a positive safe intege
- ${PLUGIN_MANIFEST_FILE} plugin at index ${index} must includ
- ${PLUGIN_MANIFEST_FILE} plugin ${candidate.id} must include
- perPage must be false or a safe integer
- ClaudeSDKAgent resumeData must include sessionId or continue
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/ad386a8fdbfebe1c.
Report an issue: GitHub.