mastra-ai/mastra · error · Error

Dynamic workflow references step "${id}" which is not regist

Error message

Dynamic workflow references step "${id}" which is not registered as an agent or tool on this Mastra instance.

What it means

A 'step' entry in a stored dynamic workflow resolves its id first as an agent, then as a tool, via `createStepFromAgent`/`createStepFromTool`. If the id matches neither, the library throws because stored plain-id step entries can only be backed by registered agents or tools.

Source

Thrown at packages/core/src/workflows/dynamic/rehydrate.ts:294

          `Dynamic workflow references tool "${entry.toolId}" which is not registered on this Mastra instance.`,
        );
      }
      return { type: 'tool', id: entry.id, toolId: entry.toolId, tool, options: rebuildToolOptions(entry) };
    }
    case 'step': {
      const { id } = entry.step;
      // Wrap the resolved agent/tool in a real Step (same adapters `createStep`
      // uses) so the entry honors the executeStep contract instead of casting a
      // raw Agent/Tool instance — those don't carry a step-shaped `execute`.
      const agent = tryGetAgentById(mastra, id);
      if (agent) {
        return { type: 'step', step: createStepFromAgent(agent) as unknown as Step };
      }
      const tool = tryGetToolById(mastra, id);
      if (tool) {
        return { type: 'step', step: createStepFromTool(tool as any) as unknown as Step };
      }
      throw new Error(
        `Dynamic workflow references step "${id}" which is not registered as an agent or tool on this Mastra instance.`,
      );
    }
    case 'workflow': {
      const nested = assertWorkflowExists(mastra, entry.workflowId);
      // Same call-site identity rule as top-level nested workflows: run the
      // clone under the declared id so results are keyed the way the portable
      // definition addresses them.
      const step = entry.id && entry.id !== nested.id ? cloneWorkflow(nested as any, { id: entry.id }) : nested;
      return { type: 'step', step: step as unknown as Step };
    }
    case 'mapping':
      throw new Error(
        `mapping entries cannot appear inside .parallel(), .branch(), or .foreach(); they must be top-level.`,
      );
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Register the referenced resource as an agent or tool on the Mastra instance so the id resolves.
  2. If the step is a plain Step, re-serialize the workflow so the step is embedded inline rather than referenced by id.
  3. Fix id mismatches between the stored graph and the registry (typo/rename).
  4. Pre-validate each stored step id with `mastra.getAgent(id) ?? mastra.getTool(id)` before rehydrating.

Example fix

// before: stored { type: 'step', id: 'myStep' } with only a local createStep()
// after: register it as a tool-backed step
const mastra = new Mastra({ tools: { myStep: createToolFromStep(myStep) } });
Defensive patterns

Strategy: validation

Validate before calling

function assertStepIdsResolvable(stored, mastra) {
  for (const e of stored.entries) {
    if (e.type === 'step') {
      const id = typeof e === 'string' ? e : e.id;
      if (id && !mastra.getAgent?.(id) && !mastra.getTool?.(id)) {
        throw new Error(`Step id "${id}" resolves to neither agent nor tool`);
      }
    }
  }
}

Type guard

function stepIdResolves(mastra: Mastra, id: string): boolean {
  return !!mastra.getAgent?.(id) || !!mastra.getTool?.(id);
}

Try / catch

try {
  const wf = rehydrateWorkflow(stored, mastra);
} catch (err) {
  const m = err instanceof Error && err.message.match(/references step "([^"]+)" which is not registered/);
  if (m) throw new Error(`'${m[1]}' must be registered as an agent or tool (plain steps cannot be referenced by id).`);
  throw err;
}

Prevention

When it happens

Trigger: rehydrateWorkflow processes a stored step entry whose id (entry.id or nested id) is not registered as an agent or tool on the Mastra instance — e.g. referencing a plain Step object that was never registered, or an id typo.

Common situations: Assuming arbitrary inline `createStep()` steps can be referenced by id in stored graphs (they must be serialized inline or registered); typos in step ids; renaming agents/tools without updating stored graphs.

Related errors


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