mastra-ai/mastra · error · Error
Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof
Error message
Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)} What it means
loadPluginManifest() reads `.mastracode-plugin.json` from the given rootDir and JSON.parse fails. The library wraps the parse error with the manifest filename and rethrows so you know which file is malformed.
Source
Thrown at mastracode/sdk/src/plugins/manifest.ts:24
export type PluginManifestEntry = {
id: string;
name?: string;
entry: string;
};
export type PluginManifest = {
plugins: PluginManifestEntry[];
};
export function loadPluginManifest(rootDir: string): PluginManifest | undefined {
const manifestPath = path.join(rootDir, PLUGIN_MANIFEST_FILE);
if (!fs.existsSync(manifestPath)) return undefined;
let parsed: unknown;
try {
parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
} catch (error) {
throw new Error(
`Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof Error ? error.message : String(error)}`,
);
}
if (!parsed || typeof parsed !== 'object' || !Array.isArray((parsed as { plugins?: unknown }).plugins)) {
throw new Error(`${PLUGIN_MANIFEST_FILE} must contain a plugins array`);
}
return {
plugins: (parsed as { plugins: unknown[] }).plugins.map((entry, index) => validateManifestEntry(entry, index)),
};
}
export function savePluginManifest(rootDir: string, manifest: PluginManifest): void {
fs.writeFileSync(path.join(rootDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}\n`);
}
export function upsertPluginManifestEntry(rootDir: string, entry: PluginManifestEntry): void {View on GitHub (pinned to 75dd419e61)
Solutions
- Open `.mastracode-plugin.json` in the reported rootDir and fix the JSON syntax error named in the message.
- Validate the file with `JSON.parse(fs.readFileSync(...))` or `node -e` / a JSON linter before rerunning.
- Regenerate the file via savePluginManifest/upsertPluginManifestEntry instead of editing by hand.
- Check the file encoding — strip BOM and ensure UTF-8.
Example fix
// before (invalid JSON)
{ "plugins": [{ "id": "a", "entry": "./a.ts", }] }
// after
{ "plugins": [{ "id": "a", "entry": "./a.ts" }] } Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
const raw = fs.readFileSync(manifestPath, 'utf8').replace(/^\uFEFF/, '');
try { JSON.parse(raw); } catch (e) { throw new Error(`Invalid .mastracode-plugin.json: ${(e as Error).message}`); } Type guard
function isValidJson(text: string): boolean {
try { JSON.parse(text); return true; } catch { return false; }
} Try / catch
try {
const manifest = loadPluginManifest(rootDir);
} catch (error) {
if (error instanceof Error && error.message.startsWith('Could not parse')) {
console.error('Fix .mastracode-plugin.json JSON syntax:', error.message);
process.exitCode = 1;
return;
}
throw error;
} Prevention
- Never hand-edit JSON with trailing commas or comments — validate after edits.
- Always write the manifest via savePluginManifest so it is well-formed.
- Strip BOM and ensure UTF-8 encoding of the file.
- Run a JSON linter in CI over `.mastracode-plugin.json` files.
When it happens
Trigger: Calling loadPluginManifest, getSingleManifestPlugin, or anything that boots the manifest plugin when `.mastracode-plugin.json` exists in rootDir but contains invalid JSON: truncated writes, comments in JSON, trailing commas, BOM, or hand-edits.
Common situations: Hand-editing the manifest and leaving a trailing comma; a failed save leaving a partially written file; copy-pasting JSON with comments or single quotes; non-UTF8 encoding.
Related errors
- Invalid JSON in presets file: ${presetsPath}
- ${PLUGIN_MANIFEST_FILE} must contain a plugins array
- ${PLUGIN_MANIFEST_FILE} contains multiple plugins. Provide a
- ${PLUGIN_MANIFEST_FILE} plugin at index ${index} must be an
- Presets file must contain a JSON object with named presets
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/74135d371869b370.
Report an issue: GitHub.