mastra-ai/mastra · error · Error

Tool does not have an execute function

Error message

Tool ${params.id} does not have an execute function

What it means

This error is thrown at execution time when the tool-wrapped step runs: the step body checks params.execute and throws if the tool has no execute function. The schema guard (1902) runs at creation, but a tool with schemas yet no execute only fails when the step actually executes.

Solutions

  1. Implement execute on the tool so it returns the tool's result.
  2. If the tool is only meant for descriptions/schema, replace the workflow step with a plain StepParams step implementing the logic.
  3. Add a startup assertion (typeof tool.execute === 'function') to catch the missing execute before a run.

Example fix

// before
const tool = { id: 'sum', inputSchema: z.object({ a: z.number(), b: z.number() }), outputSchema: z.object({ r: z.number() }) };
createStep(tool);

// after
const tool = {
  id: 'sum',
  inputSchema: z.object({ a: z.number(), b: z.number() }),
  outputSchema: z.object({ r: z.number() }),
  execute: async ({ context }) => ({ r: context.a + context.b }),
};
createStep(tool);
Defensive patterns

Strategy: validation

Validate before calling

function assertToolExecutable(tool: { id: string; execute?: unknown }) {
  if (typeof tool.execute !== 'function') {
    throw new Error(`Tool ${tool.id} must implement execute before being used in a workflow`);
  }
}

Type guard

const hasExecute = (t: any): t is { execute: (...args: any[]) => any } =>
  typeof t?.execute === 'function';

Try / catch

try {
  await runStep(toolStep, input);
} catch (e) {
  if (e instanceof Error && e.message.includes('does not have an execute function')) {
    // fall back or fail fast with tool id context
  }
  throw e;
}

Prevention

When it happens

Trigger: Executing a workflow containing a step built via createStep(tool) where tool.execute is undefined — e.g. a tool declaration missing execute, a 'toolset' stub, or a conditionally-attached execute that was never assigned.

Common situations: Abstract/base tool classes where subclasses must implement execute but the base instance was registered; tools used purely for schema inference; mocks in tests lacking execute.

Related errors


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

Appendix: source

Thrown at packages/core/src/workflows/evented/workflow.ts:690

    scorers: toolOpts?.scorers,
    metadata: toolOpts?.metadata,
    execute: async ({
      inputData,
      mastra,
      requestContext,
      suspend,
      resumeData,
      runId,
      workflowId,
      state,
      setState,
      abortSignal,
      ...obsFields
    }) => {
      const observabilityContext = resolveObservabilityContext(obsFields);
      // Tools receive (input, context) - just call the tool's execute
      if (!params.execute) {
        throw new Error(`Tool ${params.id} does not have an execute function`);
      }

      // Build context matching ToolExecutionContext structure
      const context = {
        mastra,
        requestContext,
        ...observabilityContext,
        abortSignal,
        workflow: {
          runId,
          workflowId,
          state,
          setState,
          suspend,
          resumeData,
        },
      };

View on GitHub (pinned to 75dd419e61)