{"record":{"id":"eb4b866a24a9c220","repo":"mastra-ai/mastra","slug":"presets-file-must-contain-a-json-object-with-named","errorCode":null,"errorMessage":"Presets file must contain a JSON object with named presets","messagePattern":"Presets file must contain a JSON object with named presets","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils/validate-presets.ts","lineNumber":29,"sourceCode":" */\nexport async function loadAndValidatePresets(presetsPath: string): Promise<string> {\n  const absolutePath = resolve(process.cwd(), presetsPath);\n\n  if (!existsSync(absolutePath)) {\n    throw new Error(`Presets file not found: ${absolutePath}`);\n  }\n\n  const content = await readFile(absolutePath, 'utf-8');\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(content);\n  } catch {\n    throw new Error(`Invalid JSON in presets file: ${presetsPath}`);\n  }\n\n  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n    throw new Error(`Presets file must contain a JSON object with named presets`);\n  }\n\n  // Validate each preset value is an object\n  for (const [key, value] of Object.entries(parsed)) {\n    if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n      throw new Error(`Preset \"${key}\" must be a JSON object`);\n    }\n  }\n\n  return content; // Return original string to preserve formatting\n}\n","sourceCodeStart":11,"sourceCodeEnd":41,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/utils/validate-presets.ts#L11-L41","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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 `{}`."],"exampleFix":"// before (presets.json)\n[\n  { \"temperature\": 0.7 }\n]\n// after\n{\n  \"default\": { \"temperature\": 0.7 }\n}","handlingStrategy":"type-guard","validationCode":"function isNamedPresetMap(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","typeGuard":"function isNamedPresetMap(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.prototype.toString.call(v) === '[object Object]';\n}","tryCatchPattern":"try {\n  await loadAndValidatePresets(presetsPath);\n} catch (err) {\n  if ((err as Error).message.includes('must contain a JSON object')) {\n    console.error('Presets root must be { \"name\": { ...preset } }, not an array or scalar');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["cli","json","config","schema-validation-failed"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}