mastra-ai/mastra · error · MastraError

TOOL_INVALID_FORMAT

TOOL_INVALID_FORMAT

Error message

TOOL_INVALID_FORMAT

What it means

Mastra throws `TOOL_INVALID_FORMAT` (a USER-domain MastraError) when an entry in a `tools` map is a plain function — the classic mistake of registering a tool factory (e.g. a function returned by a `createTool`-producing helper, or a Vercel-AI-SDK-style factory) instead of an actual Tool instance. Plain functions would otherwise silently fail at runtime, so this check fails fast.

Source

Thrown at packages/core/src/utils.ts:368

    inputSchema,
  };
}

/**
 * Ensures a tool has an ID and inputSchema by generating one if not present
 * @param tool - The tool to ensure has an ID and inputSchema
 * @returns The tool with an ID and inputSchema
 */
export function ensureToolProperties(tools: ToolsInput): ToolsInput {
  const toolsWithProperties = Object.keys(tools).reduce<ToolsInput>((acc, key) => {
    const tool = tools?.[key];
    if (tool) {
      // Check if the tool is a plain function (not a Tool instance or Vercel tool)
      // This catches the common mistake of passing a tool factory function instead of the tool itself
      // We need to cast to unknown first since ToolsInput doesn't include functions in its type,
      // but users can still pass functions at runtime which causes silent failures
      if (typeof tool === 'function' && !((tool as unknown) instanceof Tool) && !isVercelTool(tool)) {
        throw new MastraError({
          id: 'TOOL_INVALID_FORMAT',
          domain: ErrorDomain.TOOL,
          category: ErrorCategory.USER,
          text: `Tool "${key}" is not a valid tool format. Tools must be created using createTool() or be a valid Vercel AI SDK tool. Received a function.`,
        });
      }

      if (isVercelTool(tool)) {
        acc[key] = setVercelToolProperties(tool) as VercelTool;
      } else {
        acc[key] = tool;
      }
    }
    return acc;
  }, {});

  return toolsWithProperties;
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Call the factory: `tools: { myTool: createMyTool({...}) }` instead of passing the factory function itself.
  2. Verify the registered value with the check Mastra uses: it must be a `Tool` instance (MASTRA_TOOL_MARKER) or a Vercel tool (an object, not a function).
  3. If you truly need dynamic tool creation, build the map at config time: `tools: { myTool: myToolFactory(options) }`.

Example fix

// before
new Agent({ tools: { weather: createWeatherTool } });
// after
new Agent({ tools: { weather: createWeatherTool({ apiKey }) } });
Defensive patterns

Strategy: type-guard

Validate before calling

function assertValidToolEntries(tools: Record<string, unknown>) {
  for (const [key, tool] of Object.entries(tools)) {
    if (typeof tool === 'function') throw new Error(`tools.${key} is a function — call the factory to get the Tool instance`);
  }
}

Type guard

function isMastraTool(v: unknown): v is Tool {
  return (
    (v instanceof Tool) ||
    (typeof v === 'object' && v !== null && (v as any)[MASTRA_TOOL_MARKER] === true)
  );
}

Try / catch

try {
  new Agent({ name: 'x', tools });
} catch (e) {
  if (e instanceof MastraError && e.id === 'TOOL_INVALID_FORMAT') {
    console.error(`Fix tools entry: ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing `tools: { myTool: createMyTool(options) }` where `createMyTool` is itself the tool-returning factory but you forgot to call it, so the value is a function; passing a bare function where a `Tool` instance or Vercel tool object is expected in agent config, workflow steps, or `ensuredTools`.

Common situations: Copy-pasting tool definitions where the factory is curried with options; accidental name collision shadowing a Tool variable with its factory function; mixing Vercel AI SDK `tool()` outputs with Mastra tools incorrectly.

Related errors


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