mastra-ai/mastra · error · Error
Tool '${entry.toolId}' not found for workflow step '${entry.
Error message
Tool '${entry.toolId}' not found for workflow step '${entry.id}'. Pass the tool instance directly. What it means
A workflow step references a tool by toolId, but neither an instance on the step entry (entry.tool) nor a tool registered under that id on the Mastra instance could be resolved. runToolEntry throws this Error before executing the step.
Source
Thrown at packages/core/src/workflows/entry-executors/run-tool-entry.ts:16
import type { Mastra } from '../../mastra';
import { resolveObservabilityContext } from '../../observability';
import type { ToolStepEntry } from '../types';
import { resolveEntryActor } from './actor';
import type { EntryExecuteContext } from './types';
/**
* Runs a declarative `tool` entry: resolves the tool (inline handle, else the
* Mastra registry) and executes it with the step context mapped into the tool
* execution context.
*/
export async function runToolEntry(entry: ToolStepEntry, ctx: EntryExecuteContext, mastra?: Mastra): Promise<unknown> {
const registry = mastra ?? (ctx?.mastra as Mastra | undefined);
const tool = entry.tool ?? registry?.getTool(entry.toolId);
if (!tool) {
throw new Error(
`Tool '${entry.toolId}' not found for workflow step '${entry.id}'. Pass the tool instance directly.`,
);
}
const {
inputData,
mastra: ctxMastra,
requestContext,
suspend,
resumeData,
runId,
workflowId,
state,
setState,
abortSignal,
actor,
...rest
} = ctx;View on GitHub (pinned to 75dd419e61)
Solutions
- Register the tool on the Mastra instance: new Mastra({ tools: { myToolId: myTool } }).
- Or pass the tool instance directly on the step entry: { id: 'step', tool: myTool } (note the message says instance is required here, unlike agents).
- Verify toolId matches the registration key exactly.
- Ensure the Mastra instance is reachable by the engine (mastra param or ctx.mastra).
Example fix
// before
steps: [{ id: 'fetch', toolId: 'fetchWeather' }] // never registered
// after
steps: [{ id: 'fetch', tool: createTool({ id: 'fetchWeather', ... }) }]
// or: new Mastra({ tools: { fetchWeather: weatherTool } }) Defensive patterns
Strategy: validation
Validate before calling
const tool = entry.tool ?? mastra?.getTool(entry.toolId);
if (!tool) throw new Error(`Step '${entry.id}' references unregistered tool '${entry.toolId}'`); Type guard
function hasTool(entry: { tool?: unknown; toolId: string }, mastra?: Mastra): boolean {
return !!entry.tool || !!mastra?.getTool(entry.toolId);
} Try / catch
try { await runToolEntry(entry, ctx, mastra); } catch (e) { if (e instanceof Error && e.message.includes("Tool '") && e.message.includes("not found")) { attachToolInstance(entry); } else throw e; } Prevention
- Pass tool instances directly on dynamic workflow step entries (registration alone is not enough here).
- Register shared tools on the Mastra instance for id-based lookup.
- Centralize tool id constants to avoid drift.
- Validate all tool references resolve before executing a dynamic workflow.
When it happens
Trigger: Executing a (dynamic) workflow whose ToolStepEntry has toolId set but entry.tool undefined, while registry.getTool(entry.toolId) returns undefined — the tool was never registered on the Mastra instance or the id is wrong.
Common situations: Dynamic/codegen workflows referencing tool ids that were not registered; tools created locally but not passed to Mastra; typos or renamed tool ids; running the engine without the Mastra instance in scope.
Related errors
- Agent '${entry.agentId}' not found for workflow step '${entr
- @mastra/livekit: no workflow specified. Set `workflow` on cr
- list-available-agents requires a Mastra context.
- list-available-tools requires a Mastra context.
- list-available-workflows requires a Mastra context.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3842414e163fcaa3.
Report an issue: GitHub.