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

  1. Open `.mastracode-plugin.json` in the reported rootDir and fix the JSON syntax error named in the message.
  2. Validate the file with `JSON.parse(fs.readFileSync(...))` or `node -e` / a JSON linter before rerunning.
  3. Regenerate the file via savePluginManifest/upsertPluginManifestEntry instead of editing by hand.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/74135d371869b370. Report an issue: GitHub.