{"record":{"id":"0cd932fc9e43dd9f","repo":"mastra-ai/mastra","slug":"stored-mapping-step-stepid-has-invalid-json-m","errorCode":null,"errorMessage":"Stored mapping step \"${stepId}\" has invalid JSON mapConfig: ${(e as Error).message}","messagePattern":"Stored mapping step \"(.+?)\" has invalid JSON mapConfig: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/dynamic/mapping-config.ts","lineNumber":26,"sourceCode":" *   collects issues, and infers the mapping's output schema in the same pass\n *   (the two are inseparable — a descriptor's validity determines its\n *   contribution to the output shape).\n *\n * Template syntax checking delegates to `mapping-template.ts`'s\n * `validateTemplate` — the same parser the runtime uses — plus a scope check\n * over the placeholders' step ids.\n */\nimport { collectTemplateStepIds, validateTemplate } from '../mapping-template';\nimport type { JsonSchema } from './json-schema-to-zod';\nimport { isCanonicalMappingPath, isRecord, schemaAtPath, schemaForValue } from './validate/schema-utils';\nimport type { WorkflowValidationIssue } from './validate/types';\n\n/** Parses a stored mapConfig JSON string; throws with the step id on malformed JSON. */\nexport function parseMapConfig(raw: string, stepId: string): Record<string, any> {\n  try {\n    return JSON.parse(raw) as Record<string, any>;\n  } catch (e) {\n    throw new Error(`Stored mapping step \"${stepId}\" has invalid JSON mapConfig: ${(e as Error).message}`);\n  }\n}\n\n/** A recognizable Handlebars/Mustache placeholder: `{{ name }}`, `{{a.b}}`, … */\nconst HANDLEBARS_PLACEHOLDER = /\\{\\{\\s*[\\w$][\\w.$-]*\\s*\\}\\}/;\n\nexport interface MapConfigAnalysisOptions {\n  /** Issue path prefix of the mapping entry, e.g. `graph.2`. */\n  path: string;\n  /** Outputs of preceding workflow-local steps (schema may be undefined when unknown). */\n  availableOutputs: ReadonlyMap<string, JsonSchema | undefined>;\n  /** The workflow's input schema (for `{ initData: true }` sources). */\n  inputSchema: JsonSchema | undefined;\n  /** The workflow's request-context schema (for `{ requestContextPath }` sources). */\n  requestContextSchema: JsonSchema | undefined;\n}\n\nexport interface MapConfigAnalysis {","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/dynamic/mapping-config.ts#L8-L44","documentation":"Dynamic mapping steps persist their configuration as a JSON string in mapConfig. parseMapConfig JSON.parses that string and, if it is malformed, throws an error that names the offending step id and includes the underlying JSON.parse message, so stored workflows fail loudly instead of silently mis-mapping data.","triggerScenarios":"Rehydrating a workflow from storage whose mapping step row contains corrupted/truncated mapConfig JSON — e.g. manual DB edits, a failed write, escaping bugs when the config was saved, or an older serialization format being read by new code.","commonSituations":"Database migrations or hand-edited rows corrupting the JSON; application bug that stored a non-JSON string (e.g. a template string with unescaped quotes); restore from backup with partially written rows.","solutions":["Inspect the mapConfig column for the named step id and fix/rewrite it as valid JSON.","Re-save the mapping step via the builder/API so a correct mapConfig is persisted.","Restore the row from a backup if the config was corrupted in storage."],"exampleFix":"// before (stored mapConfig)\n{\"items\": \"{{inputs.a\",   // truncated\n// after\n{\"items\": \"{{inputs.a}}\"}","handlingStrategy":"try-catch","validationCode":"function assertValidMapConfig(raw, stepId) {\n  try { JSON.parse(raw); } catch (e) {\n    throw new Error(`mapConfig for step \"${stepId}\" is not valid JSON`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const cfg = parseMapConfig(raw, stepId);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('invalid JSON mapConfig')) {\n    // rebuild mapConfig via the builder API or restore the row from backup\n  }\n  throw e;\n}","preventionTips":["Never hand-edit stored mapConfig rows; use the builder API.","Validate JSON with JSON.parse before persisting mapConfig.","Add DB constraints/checksums to catch corrupted config rows.","Back up workflow storage before migrations."],"tags":["json","persistence","mapping"],"backgroundTag":"invalid-json-parsed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}