{"record":{"id":"19e1b628067e9a73","repo":"mastra-ai/mastra","slug":"mapping-entries-cannot-appear-inside-parallel","errorCode":null,"errorMessage":"mapping entries cannot appear inside .parallel(), .branch(), or .foreach(); they must be top-level.","messagePattern":"mapping entries cannot appear inside \\.parallel\\(\\), \\.branch\\(\\), or \\.foreach\\(\\); they must be top-level\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/dynamic/rehydrate.ts","lineNumber":307,"sourceCode":"      }\n      const tool = tryGetToolById(mastra, id);\n      if (tool) {\n        return { type: 'step', step: createStepFromTool(tool as any) as unknown as Step };\n      }\n      throw new Error(\n        `Dynamic workflow references step \"${id}\" which is not registered as an agent or tool on this Mastra instance.`,\n      );\n    }\n    case 'workflow': {\n      const nested = assertWorkflowExists(mastra, entry.workflowId);\n      // Same call-site identity rule as top-level nested workflows: run the\n      // clone under the declared id so results are keyed the way the portable\n      // definition addresses them.\n      const step = entry.id && entry.id !== nested.id ? cloneWorkflow(nested as any, { id: entry.id }) : nested;\n      return { type: 'step', step: step as unknown as Step };\n    }\n    case 'mapping':\n      throw new Error(\n        `mapping entries cannot appear inside .parallel(), .branch(), or .foreach(); they must be top-level.`,\n      );\n  }\n}\n\n/**\n * Rebuild the object shape that `.map()` accepts. Step sources remain workflow-local\n * step IDs because mapping execution resolves them from the run's step results.\n */\nfunction rehydrateMapConfig(cfg: Record<string, any>, mastra: Mastra): Record<string, any> {\n  const out: Record<string, any> = {};\n  for (const [key, source] of Object.entries(cfg)) {\n    if (!source || typeof source !== 'object') {\n      out[key] = source;\n      continue;\n    }\n    if ('template' in source) {\n      out[key] = { template: source.template };","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/dynamic/rehydrate.ts#L289-L325","documentation":"Mapping entries (variable mappings, e.g. `mapVariable` results used for `.map()` inputs) are only supported at the top level of a stored dynamic workflow graph. When rehydration finds a 'mapping' entry nested inside a `.parallel()`, `.branch()`, or `.foreach()` composite, it throws because those composites cannot contain mapping entries in the stored format.","triggerScenarios":"rehydrateWorkflow processes a stored graph where a 'mapping' entry appears as a child of a parallel, branch, or foreach composite entry. This happens if the stored graph was produced incorrectly, hand-edited, or built by code that placed mappings in nested positions the fluent API would reject.","commonSituations":"Manually constructing/serializing graph JSON without the fluent builder's guards; migrations that reshaped nested entries; custom code pushing entries directly via internals like `__pushStepFlowEntry`.","solutions":["Move the mapping to the top level of the workflow graph; restructure so composites receive pre-mapped inputs.","Rebuild the workflow with the fluent builder (`.parallel()/.branch()/.foreach()`) so invalid nesting is rejected at build time.","Fix the stored graph JSON by relocating the mapping entry out of the composite.","Add a pre-rehydration validation pass that rejects mapping entries nested under composite entries."],"exampleFix":"// before: stored graph\n{ type: 'parallel', steps: [{ type: 'mapping', ... }, { type: 'step', ... }] }\n\n// after: mapping hoisted\n{ type: 'mapping', ... }, { type: 'parallel', steps: [{ type: 'step', ... }] }","handlingStrategy":"validation","validationCode":"function assertMappingsTopLevel(graph) {\n  const COMPOSITES = new Set(['parallel', 'branch', 'foreach']);\n  for (const e of graph.entries) {\n    if (COMPOSITES.has(e.type) && Array.isArray(e.steps) && e.steps.some(s => s.type === 'mapping')) {\n      throw new Error('mapping entry found inside composite; hoist to top level');\n    }\n  }\n}","typeGuard":"function isTopLevelMapping(e: { type: string; steps?: unknown[] }): boolean {\n  return e.type === 'mapping';\n}","tryCatchPattern":"try {\n  const wf = rehydrateWorkflow(stored, mastra);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('mapping entries cannot appear inside')) {\n    // rebuild graph with mapping hoisted to top level\n  }\n  throw err;\n}","preventionTips":["Build graphs with the fluent builder so invalid nesting is rejected at construction time.","Never hand-author composite entries containing mapping children.","Run a structural validator over stored graphs before rehydration."],"tags":["workflow","mapping","structure","rehydration"],"backgroundTag":"invalid-workflow-graph-nesting","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}