mastra-ai/mastra · error · Error
${describeBadPlaceholder(template, idx, rawExpr)} references
Error message
${describeBadPlaceholder(template, idx, rawExpr)} references unknown namespace "${scope}". Use one of: ${TEMPLATE_NAMESPACES.join(', ')}. What it means
Template placeholders must use one of the known TEMPLATE_NAMESPACES scopes (e.g. stepResults, requestContext, and other supported namespaces). An unrecognized scope like "${input.foo}" or "${results.x}" is rejected with the list of valid namespaces.
Source
Thrown at packages/core/src/workflows/mapping-template.ts:83
const innerDot = rest.indexOf('.');
const stepId = innerDot === -1 ? rest : rest.slice(0, innerDot);
if (!stepId) {
throw new Error(
`${describeBadPlaceholder(template, idx, rawExpr)} must be of the form \${stepResults.<stepId>} or \${stepResults.<stepId>.<path>}.`,
);
}
continue;
}
if (scope === 'requestContext') {
if (!rest) {
throw new Error(
`${describeBadPlaceholder(template, idx, rawExpr)} requires a request-context key — use \${requestContext.<key>}.`,
);
}
continue;
}
if ((TEMPLATE_NAMESPACES as readonly string[]).includes(scope)) continue;
throw new Error(
`${describeBadPlaceholder(template, idx, rawExpr)} references unknown namespace "${scope}". ` +
`Use one of: ${TEMPLATE_NAMESPACES.join(', ')}.`,
);
}
}
/**
* Collects the step ids referenced by `${stepResults.<stepId>}` /
* `${stepResults.<stepId>.<path>}` placeholders in a template. Assumes the
* template already passed {@link validateTemplate}; malformed placeholders are
* skipped. Used by validation to scope-check template references against the
* preceding workflow-local steps.
*/
export function collectTemplateStepIds(template: string): string[] {
const ids: string[] = [];
for (const match of template.matchAll(TEMPLATE_PLACEHOLDER)) {
const { scope, rest } = parseTemplatePlaceholder(match[1] ?? '');
if (scope !== 'stepResults') continue;View on GitHub (pinned to 75dd419e61)
Solutions
- Use a valid namespace from the error message list, e.g. "${stepResults.myStep.field}" or "${requestContext.key}".
- Fix near-miss typos ("stepResult" -> "stepResults").
- Grep your codebase for '${' templates and lint them with validateTemplate() in CI.
Example fix
// before
mapVariable({ value: '${results.fetchUser.id}' });
// after
mapVariable({ value: '${stepResults.fetchUser.id}' }); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = ['stepResults', 'requestContext' /* plus other TEMPLATE_NAMESPACES */];
for (const m of tpl.matchAll(/\$\{([^}]*)\}/g)) {
const scope = m[1].split('.')[0];
if (!KNOWN.includes(scope)) throw new Error(`Unknown namespace '${scope}' in ${m[0]}; use one of ${KNOWN.join(', ')}`);
} Try / catch
try {
validateTemplate(tpl);
} catch (err) {
if (err instanceof Error && err.message.includes('unknown namespace')) {
console.error(err.message); // lists valid namespaces to use
} else throw err;
} Prevention
- Only use namespaces from the error's 'Use one of:' list.
- Common near-miss: singular 'stepResult' instead of 'stepResults'.
- Run validateTemplate() over all templates in CI.
When it happens
Trigger: Using an invented scope such as "${input.value}", "${context.key}", "${results.myStep}" in a mapping template; mixing up scope names from other libraries.
Common situations: Guessing scope names without checking docs; migrating templates from another workflow engine; typos like "stepResult" (singular).
Related errors
- ${describeBadPlaceholder(template, idx, rawExpr)} has empty
- ${describeBadPlaceholder(template, idx, rawExpr)} must be of
- mapping entries cannot appear inside .parallel(), .branch(),
- Mapping references unknown workflow init-data "${source.init
- Invalid path ${path} in ${errorLabel}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b8c949fa990c139f.
Report an issue: GitHub.