{"record":{"id":"cbf0745ec58bb883","repo":"mastra-ai/mastra","slug":"invalid-arguments-for-firecrawl-extract","errorCode":null,"errorMessage":"Invalid arguments for firecrawl_extract","messagePattern":"Invalid arguments for firecrawl_extract","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/__fixtures__/fire-crawl-complex-schema.ts","lineNumber":787,"sourceCode":"            )\n            .join('\\n\\n');\n\n          return {\n            content: [{ type: 'text', text: trimResponseText(results) }],\n            isError: false,\n          };\n        } catch (error) {\n          const errorMessage = error instanceof Error ? error.message : `Search failed: ${JSON.stringify(error)}`;\n          return {\n            content: [{ type: 'text', text: trimResponseText(errorMessage) }],\n            isError: true,\n          };\n        }\n      }\n\n      case 'firecrawl_extract': {\n        if (!isExtractOptions(args)) {\n          throw new Error('Invalid arguments for firecrawl_extract');\n        }\n\n        try {\n          const extractStartTime = Date.now();\n\n          safeLog('info', `Starting extraction for URLs: ${args.urls.join(', ')}`);\n\n          const extractResponse = await withRetry(\n            async () =>\n              client.extract(args.urls, {\n                prompt: args.prompt,\n                systemPrompt: args.systemPrompt,\n                schema: args.schema,\n                allowExternalLinks: args.allowExternalLinks,\n                enableWebSearch: args.enableWebSearch,\n                includeSubdomains: args.includeSubdomains,\n              } as ExtractParams),\n            'extract operation',","sourceCodeStart":769,"sourceCodeEnd":805,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/__fixtures__/fire-crawl-complex-schema.ts#L769-L805","documentation":"The firecrawl_extract tool validates args with isExtractOptions(args) before executing. Extraction requires a non-empty `urls` array of valid http(s) URLs plus optional boolean/enum fields; failing that shape throws this error before any API request. Like the other firecrawl guards, it exists because MCP clients can send arbitrary JSON as tool arguments.","triggerScenarios":"args fails isExtractOptions: urls missing, not an array, empty array, or containing non-URL strings; includeSubdomains/ignoreInvalidURLs present but not booleans; prompt or schema fields of wrong type.","commonSituations":"Client sends urls as a comma-separated string instead of an array; LLM produces a single string for urls; schema/prompt passed as JSON string instead of object; forgetting that extract requires at least one URL or a prompt.","solutions":["Pass urls as a non-empty array of valid http(s) URL strings.","Ensure optional flags (includeSubdomains, ignoreInvalidURLs, waitFor, etc.) have correct types per isExtractOptions.","Check the firecrawl_extract tool's Zod input schema and align your arguments exactly.","For LLM callers, add a JSON-schema precondition so invalid extract args are corrected before tool execution."],"exampleFix":"// before\nfirecrawl_extract({ urls: \"https://a.com,https://b.com\" })\n// after\nfirecrawl_extract({ urls: [\"https://a.com\", \"https://b.com\"], includeSubdomains: false })","handlingStrategy":"validation","validationCode":"function canCallExtract(args) {\n  return (\n    !!args &&\n    Array.isArray(args.urls) &&\n    args.urls.length > 0 &&\n    args.urls.every(u => {\n      try { const p = new URL(u); return p.protocol === 'http:' || p.protocol === 'https:'; }\n      catch { return false; }\n    }) &&\n    (args.includeSubdomains === undefined || typeof args.includeSubdomains === 'boolean') &&\n    (args.ignoreInvalidURLs === undefined || typeof args.ignoreInvalidURLs === 'boolean')\n  );\n}","typeGuard":"function isExtractArgs(a: unknown): a is { urls: string[]; includeSubdomains?: boolean; ignoreInvalidURLs?: boolean } {\n  if (typeof a !== 'object' || a === null) return false;\n  const o = a as Record<string, unknown>;\n  return Array.isArray(o.urls) && o.urls.length > 0 && o.urls.every((u): u is string => typeof u === 'string') &&\n    (o.includeSubdomains === undefined || typeof o.includeSubdomains === 'boolean');\n}","tryCatchPattern":"try {\n  return await firecrawlExtract(args);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid arguments for firecrawl_extract')) {\n    // normalize common mistakes: string -> array\n    if (typeof args?.urls === 'string') return firecrawlExtract({ ...args, urls: args.urls.split(',').map(s => s.trim()) });\n    throw new TypeError('extract needs urls: string[] of http(s) URLs');\n  }\n  throw e;\n}","preventionTips":["Always send urls as an array, never a comma-separated string.","Validate each URL with new URL() before calling.","Set ignoreInvalidURLs: true to tolerate a few bad URLs in a batch.","Regenerate client stubs when the tool schema changes to avoid field type drift."],"tags":["mcp","validation","tool-arguments","firecrawl"],"backgroundTag":"invalid-tool-arguments","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}