mastra-ai/mastra · error · Error

Preset "${key}" must be a JSON object

Error message

Preset "${key}" must be a JSON object

What it means

Every top-level entry in the presets object must itself be a JSON object (the preset definition). If any value is a scalar (string, number, boolean), null, or an array, this error names the offending preset key. The message includes the key so you know exactly which entry to fix.

Source

Thrown at packages/cli/src/utils/validate-presets.ts:35

  }

  const content = await readFile(absolutePath, 'utf-8');

  let parsed: unknown;
  try {
    parsed = JSON.parse(content);
  } catch {
    throw new Error(`Invalid JSON in presets file: ${presetsPath}`);
  }

  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
    throw new Error(`Presets file must contain a JSON object with named presets`);
  }

  // Validate each preset value is an object
  for (const [key, value] of Object.entries(parsed)) {
    if (typeof value !== 'object' || value === null || Array.isArray(value)) {
      throw new Error(`Preset "${key}" must be a JSON object`);
    }
  }

  return content; // Return original string to preserve formatting
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure each named preset is a full object of preset options, not a scalar or array.
  2. Delete unused/null presets instead of setting them to null.
  3. If you stored a list of variants, promote it to named object entries.

Example fix

// before
{ "fast": "openai/gpt-4o", "unused": null }
// after
{ "fast": { "model": "openai/gpt-4o" } }
Defensive patterns

Strategy: type-guard

Validate before calling

function allPresetsAreObjects(v: unknown): boolean {
  return typeof v === 'object' && v !== null && !Array.isArray(v) &&
    Object.values(v).every(p => typeof p === 'object' && p !== null && !Array.isArray(p));
}

Type guard

function isPresetValue(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

try {
  await loadAndValidatePresets(presetsPath);
} catch (err) {
  const m = /Preset "(.+)" must be a JSON object/.exec((err as Error).message);
  if (m) {
    console.error(`Preset "${m[1]}" must be an object; replace the scalar/array with a preset config object`);
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: `mastra dev`/`mastra studio` given a presets file where some preset maps to a non-object, e.g. `{ "default": null }`, `{ "fast": "gpt-4" }`, or `{ "list": [...] }`.

Common situations: Abbreviating a preset to just a model name string, nulling out an unused preset, or flattening what should be nested preset config into an array.

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


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