mastra-ai/mastra · error · Error

Invalid arguments for firecrawl_crawl

Error message

Invalid arguments for firecrawl_crawl

What it means

The firecrawl_crawl branch validates args with `isCrawlOptions` (object with string `url`). On failure it throws before starting the async crawl via `withRetry(() => client.asyncCrawlUrl(...))`.

Source

Thrown at packages/mcp/src/__fixtures__/fire-crawl-complex-schema.ts:711

        const { url, ...options } = args;
        const response = await client.mapUrl(url, {
          ...options,
        });
        if ('error' in response) {
          throw new Error(response.error);
        }
        if (!response.links) {
          throw new Error('No links received from Firecrawl API');
        }
        return {
          content: [{ type: 'text', text: trimResponseText(response.links.join('\n')) }],
          isError: false,
        };
      }

      case 'firecrawl_crawl': {
        if (!isCrawlOptions(args)) {
          throw new Error('Invalid arguments for firecrawl_crawl');
        }
        const { url, ...options } = args;
        const response = await withRetry(async () => client.asyncCrawlUrl(url, { ...options }), 'crawl operation');

        if (!response.success) {
          throw new Error(response.error);
        }

        return {
          content: [
            {
              type: 'text',
              text: trimResponseText(`Started crawl for ${url} with job ID: ${response.id}`),
            },
          ],
          isError: false,
        };
      }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Always include a string `url` as the crawl starting point.
  2. Use the exact key name `url`, not `startUrl`/`baseUrl`.
  3. Validate arguments against the tool's inputSchema in the calling client.

Example fix

// before
firecrawl_crawl({ 'startUrl': 'https://example.com', limit: 10 })
// after
firecrawl_crawl({ 'url': 'https://example.com', limit: 10 })
Defensive patterns

Strategy: validation

Validate before calling

if (!args || typeof args !== 'object' || typeof (args as any).url !== 'string') {
  throw new TypeError('firecrawl_crawl requires { url: string, limit?, maxDepth? }');
}

Type guard

function isCrawlOptions(a: unknown): a is { url: string } & Record<string, unknown> {
  return typeof a === 'object' && a !== null && 'url' in a && typeof (a as { url: unknown }).url === 'string';
}

Try / catch

try {
  await callTool({ name: 'firecrawl_crawl', arguments: { url, limit: 10 } });
} catch (e) {
  if ((e as Error).message === 'Invalid arguments for firecrawl_crawl') {
    // repair payload so url is present and a string, then retry
  }
}

Prevention

When it happens

Trigger: Calling firecrawl_crawl with a missing or non-string `url`, or a non-object payload — e.g. `{"arguments":{"limit":10}}`.

Common situations: The LLM passes only crawl tuning options (limit, maxDepth) and forgets `url`, or nests the URL under a wrong key like `startUrl`.

Related errors


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