{"record":{"id":"16fd608a0a06f564","repo":"mastra-ai/mastra","slug":"describebadplaceholder-template-idx-rawexpr-16fd60","errorCode":null,"errorMessage":"${describeBadPlaceholder(template, idx, rawExpr)} must be of the form ${stepResults.<stepId>} or ${stepResults.<stepId>.<path>}.","messagePattern":"(.+?) must be of the form (.+?) or (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/mapping-template.ts","lineNumber":68,"sourceCode":" * the value a primitive) stay in {@link resolveTemplate}.\n */\nexport function validateTemplate(template: string): void {\n  let idx = 0;\n  for (const match of template.matchAll(TEMPLATE_PLACEHOLDER)) {\n    idx++;\n    const rawExpr = match[1] ?? '';\n    if (rawExpr.length === 0 || rawExpr !== rawExpr.trim()) {\n      throw new Error(\n        `${describeBadPlaceholder(template, idx, rawExpr)} has empty or whitespace-padded contents. ` +\n          `Use \\${<scope>.<path>} with no surrounding whitespace.`,\n      );\n    }\n    const { scope, rest } = parseTemplatePlaceholder(rawExpr);\n    if (scope === 'stepResults') {\n      const innerDot = rest.indexOf('.');\n      const stepId = innerDot === -1 ? rest : rest.slice(0, innerDot);\n      if (!stepId) {\n        throw new Error(\n          `${describeBadPlaceholder(template, idx, rawExpr)} must be of the form \\${stepResults.<stepId>} or \\${stepResults.<stepId>.<path>}.`,\n        );\n      }\n      continue;\n    }\n    if (scope === 'requestContext') {\n      if (!rest) {\n        throw new Error(\n          `${describeBadPlaceholder(template, idx, rawExpr)} requires a request-context key — use \\${requestContext.<key>}.`,\n        );\n      }\n      continue;\n    }\n    if ((TEMPLATE_NAMESPACES as readonly string[]).includes(scope)) continue;\n    throw new Error(\n      `${describeBadPlaceholder(template, idx, rawExpr)} references unknown namespace \"${scope}\". ` +\n        `Use one of: ${TEMPLATE_NAMESPACES.join(', ')}.`,\n    );","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/mapping-template.ts#L50-L86","documentation":"For placeholders scoped to stepResults, the expression must contain a step ID: ${stepResults.<stepId>} or ${stepResults.<stepId>.<path>}. If there is no step ID (e.g. \"${stepResults}\" or \"${stepResults.}\"), the template is invalid and validateTemplate throws.","triggerScenarios":"Templates like \"${stepResults}\" or \"${stepResults..path}\" where the step ID portion before the first dot is empty.","commonSituations":"Forgetting the step ID entirely; double dots after refactoring; autocompletion inserting just the scope name.","solutions":["Add the step ID: \"${stepResults.myStep}\" or \"${stepResults.myStep.output.field}\".","Fix accidental double dots or trailing dots in the expression.","Add a validateTemplate() unit test over all mapping constants to catch this before runtime."],"exampleFix":"// before\nmapVariable({ value: '${stepResults.}' });\n// after\nmapVariable({ value: '${stepResults.fetchUser.name}' });","handlingStrategy":"validation","validationCode":"const tpl = '${stepResults.fetchUser.name}';\nfor (const m of tpl.matchAll(/\\$\\{([^}]*)\\}/g)) {\n  const [scope, ...rest] = m[1].split('.');\n  if (scope === 'stepResults' && (!rest[0] || !rest[0].trim())) {\n    throw new Error(`Placeholder '${m[0]}' is missing a step ID`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  validateTemplate(tpl);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('stepResults.<stepId>')) {\n    console.error(`Template '${tpl}' needs a step ID after stepResults`);\n  } else throw err;\n}","preventionTips":["Always write stepResults.<stepId> or stepResults.<stepId>.<path> — never the bare scope.","Extract templates into typed constants and validate them in tests.","Beware of double/trailing dots introduced during manual edits."],"tags":["workflow","template","mapping","syntax"],"backgroundTag":"template-syntax-error","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}