mastra-ai/mastra · error · HTTPException

Tool ID is required

Error message

Tool ID is required

What it means

A 400 validation error from the tool execution endpoint when the request omits the toolId parameter entirely. The handler requires toolId before attempting any tool resolution.

Source

Thrown at packages/server/src/server/handlers/tools.ts:238

  },
});

export const EXECUTE_TOOL_ROUTE = createRoute({
  method: 'POST',
  path: '/tools/:toolId/execute',
  responseType: 'json',
  pathParamSchema: toolIdPathParams,
  queryParamSchema: optionalRunIdSchema,
  bodySchema: executeToolContextBodySchema,
  responseSchema: executeToolResponseSchema,
  summary: 'Execute tool',
  description: 'Executes a specific tool with the provided input data',
  tags: ['Tools'],
  requiresAuth: true,
  handler: async ({ mastra, runId, toolId, registeredTools, requestContext, ...bodyParams }) => {
    try {
      if (!toolId) {
        throw new HTTPException(400, { message: 'Tool ID is required' });
      }

      let tool: any;

      // Try explicit registeredTools first, then fallback to mastra
      if (registeredTools && Object.keys(registeredTools).length > 0) {
        tool = Object.values(registeredTools).find((t: any) => t.id === toolId);
      }
      if (!tool) {
        try {
          tool = mastra.getToolById(toolId);
        } catch {
          // tool not found in global registry, continue to agent fallback
        }
      }

      // Fallback: search dynamically-resolved agent tools (toolsResolver)
      if (!tool) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include the toolId in the request path or body when calling the execute endpoint.
  2. Ensure your client serializes route params and doesn't drop them (check URL construction).
  3. Fetch the tool list first and pass a valid toolId.

Example fix

// before
await api.post('/api/tools/execute', { data: { city: 'Tokyo' } }); // 400
// after
await api.post(`/api/tools/${toolId}/execute`, { data: { city: 'Tokyo' } });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof toolId !== 'string' || toolId.trim() === '') {
  throw new Error('toolId is required to execute a tool');
}

Type guard

function hasToolId(args: { toolId?: string }): args is { toolId: string } {
  return typeof args.toolId === 'string' && args.toolId.length > 0;
}

Prevention

When it happens

Trigger: POST to the tool execution route with no toolId in path/body (or toolId resolving to undefined/null/empty), e.g. calling the execute endpoint directly without identifying which tool to run.

Common situations: Building custom client code that forgets to pass the tool ID; generic proxy that strips route params; calling the execute endpoint instead of a tool-specific nested route.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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