mastra-ai/mastra · error · HTTPException

Agent ID is required

Error message

Agent ID is required

What it means

This 400 error is thrown by the GET agent-tool route handler in packages/server when a request to fetch a specific tool assigned to an agent arrives without an agentId path parameter. The server requires the agent identifier to resolve the agent via getAgentFromSystem before it can enumerate its tools. It indicates a malformed route invocation rather than a missing tool.

Source

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

// ============================================================================
// Agent Tool Routes
// ============================================================================

export const GET_AGENT_TOOL_ROUTE = createRoute({
  method: 'GET',
  path: '/agents/:agentId/tools/:toolId',
  responseType: 'json',
  pathParamSchema: agentToolPathParams,
  responseSchema: serializedToolSchema,
  summary: 'Get agent tool',
  description: 'Returns details for a specific tool assigned to the agent',
  tags: ['Agents', 'Tools'],
  requiresAuth: true,
  handler: async ({ mastra, agentId, toolId, requestContext }) => {
    try {
      if (!agentId) {
        throw new HTTPException(400, { message: 'Agent ID is required' });
      }
      const agent = await getAgentFromSystem({ mastra, agentId });

      const agentTools = await agent.listTools({ requestContext });

      const tool = Object.values(agentTools || {}).find((tool: any) => tool.id === toolId) as any;

      if (!tool) {
        throw new HTTPException(404, { message: 'Tool not found' });
      }

      return serializeTool(tool);
    } catch (error) {
      return handleError(error, 'Error getting agent tool');
    }
  },
});

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include a valid, non-empty agentId in the URL path when calling the agent tool endpoint.
  2. Log/inspect the request URL on the client to confirm the agentId segment is populated before sending.
  3. If building requests dynamically, assert agentId is a non-empty string before dispatching.
  4. Update client SDK/playground code to match the current route contract in packages/server.

Example fix

// before
const res = await fetch(`/api/agents/${agentId}/tools/${toolId}`); // agentId undefined -> "/api/agents//tools/x"
// after
if (!agentId) throw new Error('agentId is required');
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}/tools/${encodeURIComponent(toolId)}`);
Defensive patterns

Strategy: validation

Validate before calling

function assertAgentId(agentId: unknown): asserts agentId is string {
  if (typeof agentId !== 'string' || agentId.trim() === '') {
    throw new Error('agentId must be a non-empty string before calling the agent tool endpoint');
  }
}

Type guard

function hasAgentId(a: { agentId?: string | null }): a is { agentId: string } {
  return typeof a.agentId === 'string' && a.agentId.length > 0;
}

Try / catch

try {
  const res = await fetch(`/api/agents/${agentId}/tools/${toolId}`);
  if (res.status === 400) throw new Error('Request rejected: check agentId/toolId path params');
  return await res.json();
} catch (err) {
  console.error('getAgentTool failed', err);
  throw err;
}

Prevention

When it happens

Trigger: Calling GET /api/agents//tools/:toolId (empty agentId segment), or programmatically invoking the route handler with agentId undefined/null (e.g. a client SDK or proxy stripping the path param).

Common situations: Templated URL construction where a variable is empty or undefined (e.g. `/api/agents/${agentId}/tools/${toolId}` with unset agentId), misconfigured reverse proxy rewriting that drops a path segment, or older client SDKs whose route signature changed after a server version upgrade.

Related errors


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