mastra-ai/mastra · error · Error

${label} references stepResults.${stepId} but step "${stepId

Error message

${label} references stepResults.${stepId} but step "${stepId}" has no successful output (not run yet, not registered, failed, or produced no output).

What it means

Resolving ${stepResults.<stepId>...} requires that the referenced step has a successful (non-nullish) result in the mapping context. If getStepResult(stepId) returns null/undefined — the step hasn't run, isn't registered in this workflow, failed, or succeeded with undefined output — the template cannot be resolved and it throws explaining why.

Source

Thrown at packages/core/src/workflows/mapping-template.ts:171

    case 'inputData':
      return stringifyTemplateValue(traverseMappingPath(ctx.inputData, rest, label), template, idx, rawExpr);
    case 'initData':
      return stringifyTemplateValue(traverseMappingPath(ctx.getInitData(), rest, label), template, idx, rawExpr);
    case 'state':
      return stringifyTemplateValue(traverseMappingPath(ctx.state, rest, label), template, idx, rawExpr);
    case 'requestContext':
      return stringifyTemplateValue(ctx.requestContext.get(rest), template, idx, rawExpr);
    case 'stepResults': {
      const innerDot = rest.indexOf('.');
      const stepId = innerDot === -1 ? rest : rest.slice(0, innerDot);
      const subPath = innerDot === -1 ? '' : rest.slice(innerDot + 1);
      const stepResult = ctx.getStepResult(stepId);
      // Nullish (not just null) so a step that "succeeded" with `undefined`
      // output is reported as missing too — consistent with how predicates
      // treat nullish step results. Nullish *path values inside* a present
      // result still render as '' via stringifyTemplateValue.
      if (stepResult == null) {
        throw new Error(
          `${label} references stepResults.${stepId} but step "${stepId}" has no successful output ` +
            `(not run yet, not registered, failed, or produced no output).`,
        );
      }
      return stringifyTemplateValue(traverseMappingPath(stepResult, subPath, label), template, idx, rawExpr);
    }
    default:
      // validateTemplate guarantees this branch is unreachable for well-formed
      // workflows; this is a safety net for templates that bypassed validation
      // (e.g. constructed programmatically and pushed into stepFlow).
      throw new Error(
        `${label} references unknown namespace "${scope}". Use one of: ${TEMPLATE_NAMESPACES.join(', ')}.`,
      );
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure the referenced step runs BEFORE the mapping/variable is used in the workflow graph.
  2. Fix the step ID to match the registered step's ID (check the error's stepId against createWorkflow's step list).
  3. If the step is conditionally skipped, guard the template/mapping or supply a fallback via requestContext or an earlier step.
  4. Make the producing step return a defined output (at minimum an object) even on trivial success.

Example fix

// before
// step chain: evaluate -> uses ${stepResults.fetchUser.name}, but fetchUser runs after evaluate
.then(evaluate)
.then(fetchUser)
// after
.then(fetchUser)
.then(evaluate) // now stepResults.fetchUser exists when evaluate maps
Defensive patterns

Strategy: validation

Validate before calling

const snap = run.workflowRunStatus;
const registeredStepIds = workflow.stepGraph ? Object.keys(workflow.stepGraph) : [];
const tpl = '${stepResults.fetchUser.name}';
const id = tpl.match(/\$\{stepResults\.([^.}]+)/)?.[1];
if (id && !registeredStepIds.includes(id)) throw new Error(`${id} is not a step in this workflow`);

Try / catch

try {
  run.workflow.mapVariable({ value: '${stepResults.fetchUser.name}' });
} catch (err) {
  if (err instanceof Error && err.message.includes('has no successful output')) {
    console.error('Check step ordering/registration: fetchUser must run and succeed before this mapping');
  } else throw err;
}

Prevention

When it happens

Trigger: A mapping template references stepResults.someStep while someStep runs after the mapping point, belongs to a different workflow (not registered), failed, or returned undefined; also triggered when a step "succeeds" with undefined output.

Common situations: Referencing a step that executes later in the flow (ordering mistake); typos in step IDs; steps wrapped/renamed during refactors; conditional branches where the step didn't execute on this path.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/55e289251fcbc173. Report an issue: GitHub.