mastra-ai/mastra · error · Error
Presets file must contain a JSON object with named presets
Error message
Presets file must contain a JSON object with named presets
What it means
loadAndValidatePresets() requires the top-level parsed JSON to be an object (a map of preset name to preset definition). If the file parses but its root is an array, a string, a number, boolean, or null, this error is thrown. Presets must be keyed by name.
Source
Thrown at packages/cli/src/utils/validate-presets.ts:29
*/
export async function loadAndValidatePresets(presetsPath: string): Promise<string> {
const absolutePath = resolve(process.cwd(), presetsPath);
if (!existsSync(absolutePath)) {
throw new Error(`Presets file not found: ${absolutePath}`);
}
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
- Wrap presets in a named object: `{ "presetName": { ...preset } }`.
- If you have an array, convert it to a map keyed by preset name before saving.
- Replace a null/empty placeholder file with a valid empty object `{}`.
Example fix
// before (presets.json)
[
{ "temperature": 0.7 }
]
// after
{
"default": { "temperature": 0.7 }
} Defensive patterns
Strategy: type-guard
Validate before calling
function isNamedPresetMap(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Type guard
function isNamedPresetMap(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.prototype.toString.call(v) === '[object Object]';
} Try / catch
try {
await loadAndValidatePresets(presetsPath);
} catch (err) {
if ((err as Error).message.includes('must contain a JSON object')) {
console.error('Presets root must be { "name": { ...preset } }, not an array or scalar');
process.exit(1);
}
throw err;
} Prevention
- Keep a checked-in example presets file with the correct shape.
- Validate with Zod (z.record(z.string(), z.object({}))) before saving/exporting.
- Never export arrays of presets directly; key them by name.
When it happens
Trigger: `mastra dev`/`mastra studio` given a presets file whose root is a JSON array (e.g. `[{...}]`), a bare value (`"foo"`, `42`, `true`, `null`), or an empty/null document.
Common situations: Exporting an array of presets from a script instead of a named map, writing `null` for an empty presets file, or accidentally serializing the wrong variable.
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
- Preset "${key}" must be a JSON object
- Invalid JSON in presets file: ${presetsPath}
- Could not parse ${PLUGIN_MANIFEST_FILE}: ${error instanceof
- MISSING_INPUT
- INVALID_JSON
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/eb4b866a24a9c220.
Report an issue: GitHub.