{"record":{"id":"e7fef588cafbe5c8","repo":"mastra-ai/mastra","slug":"invalid-json-in-presets-file-presetspath","errorCode":null,"errorMessage":"Invalid JSON in presets file: ${presetsPath}","messagePattern":"Invalid JSON in presets file: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils/validate-presets.ts","lineNumber":25,"sourceCode":" *\n * @param presetsPath - Path to the presets JSON file (relative or absolute)\n * @returns The original JSON string content\n * @throws Error if file doesn't exist, JSON is invalid, or structure is incorrect\n */\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":7,"sourceCodeEnd":41,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/utils/validate-presets.ts#L7-L41","documentation":"After reading the presets file, loadAndValidatePresets() runs JSON.parse and throws this error if parsing fails. The file exists but its contents are not valid JSON. Note the message uses the original (possibly relative) presetsPath argument, not the absolute path.","triggerScenarios":"`mastra dev`/`mastra studio` pointed at a presets file containing syntax errors: trailing commas, single quotes, comments (JSONC), unquoted keys, truncated content, or a file saved in a non-UTF-8/BOM-encoded format.","commonSituations":"Hand-editing the presets file and leaving a trailing comma, pasting JSON5/JSONC config with comments, a partially written file from a crashed process, or a template placeholder (${...}) left un-substituted.","solutions":["Run the file through a JSON parser to find the syntax error: `node -e \"JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))\" <path>` or a linter.","Remove JSON-incompatible syntax: trailing commas, comments, single quotes, unquoted keys.","Strip a UTF-8 BOM if present and ensure the file is UTF-8 encoded."],"exampleFix":"// before (presets.json)\n{\n  \"default\": { \"temperature\": 0.7, }, // trailing comma + comment\n}\n// after\n{\n  \"default\": { \"temperature\": 0.7 }\n}","handlingStrategy":"validation","validationCode":"function assertValidJsonFile(path: string): boolean {\n  try {\n    JSON.parse(require('node:fs').readFileSync(path, 'utf8'));\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await loadAndValidatePresets(presetsPath);\n} catch (err) {\n  if ((err as Error).message.startsWith('Invalid JSON in presets file')) {\n    const raw = require('node:fs').readFileSync(presetsPath, 'utf8').replace(/^\\uFEFF/, '');\n    try { JSON.parse(raw); } catch (e) { console.error(`JSON syntax error at ${(e as Error).message}`); }\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Lint presets files with a JSON parser/CI step before running the CLI.","Avoid hand-editing: generate the file programmatically with JSON.stringify.","Save files as UTF-8 without BOM and never add comments/trailing commas."],"tags":["cli","json","config","parse-error"],"backgroundTag":"invalid-json","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}