mastra-ai/mastra · error · Error
${response.error || 'Deep research failed'}
Error message
${response.error || 'Deep research failed'} What it means
After the deep research job finishes, the executor checks response.success and throws the API's error message, defaulting to 'Deep research failed'. Deep research runs scraping + analysis steps server-side at Firecrawl, so failures include per-page scrape failures aggregated into the job as well as auth/credit/limit issues.
Source
Thrown at packages/mcp/src/__fixtures__/fire-crawl-complex-schema.ts:868
const response = await client.deepResearch(
args.query as string,
{
maxDepth: args.maxDepth as number,
timeLimit: args.timeLimit as number,
maxUrls: args.maxUrls as number,
},
activity => {
safeLog('info', `Research activity: ${activity.message} (Depth: ${activity.depth})`);
},
source => {
safeLog('info', `Research source found: ${source.url}${source.title ? ` - ${source.title}` : ''}`);
},
);
safeLog('info', `Deep research completed in ${Date.now() - researchStartTime}ms`);
if (!response.success) {
throw new Error(response.error || 'Deep research failed');
}
const formattedResponse = {
finalAnalysis: response.data.finalAnalysis,
activities: response.data.activities,
sources: response.data.sources,
};
return {
content: [
{
type: 'text',
text: trimResponseText(formattedResponse.finalAnalysis),
},
],
isError: false,
};
} catch (error) {View on GitHub (pinned to 75dd419e61)
Solutions
- Surface response.error to identify whether it was auth, credits, rate limit, or scrape failures.
- Reduce job scope (lower maxUrls/maxDepth/timeLimit) to lower cost and failure probability.
- Confirm API key and credit balance; upgrade plan if deep research is credit-hungry.
- Retry with backoff for transient 429/5xx causes, and check Firecrawl status for outages.
Example fix
// before
if (!response.success) {
throw new Error(response.error || 'Deep research failed');
}
// after
if (!response.success) {
const detail = response.error || 'no error detail returned';
if (/credit|quota/i.test(detail)) throw new Error('Firecrawl credits exhausted: ' + detail);
if (/rate limit/i.test(detail)) throw new RetryableError(detail);
throw new Error(`Deep research failed: ${detail}`);
} Defensive patterns
Strategy: retry
Validate before calling
// Budget pre-check to reduce mid-job failures:
if (!args?.query) throw new TypeError('query required');
if ((args.maxUrls ?? Infinity) * (args.maxDepth ?? Infinity) > 500) {
console.warn('Deep research job may be credit-expensive; consider lowering maxUrls/maxDepth');
} Type guard
function isDeepResearchSuccess(res: unknown): res is { success: true; data: { finalAnalysis: string; activities?: unknown[]; sources?: unknown[] } } {
return typeof res === 'object' && res !== null && (res as any).success === true && !!res.data?.finalAnalysis;
} Try / catch
try {
const res = await firecrawlDeepResearch(args);
if (!res.success) throw new Error(res.error || 'Deep research failed');
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (/rate limit|429|temporarily/i.test(msg)) return withBackoff(() => firecrawlDeepResearch(smallerScope(args)), 3);
if (/credit|quota/i.test(msg)) throw new Error('Insufficient Firecrawl credits for deep research');
throw e;
} Prevention
- Scope jobs conservatively (maxUrls, maxDepth, timeLimit) to avoid credit exhaustion mid-run.
- Retry only transient failures; auth/credit errors need human action.
- Monitor Firecrawl status page before long research jobs.
- Persist response.error details for post-mortem rather than the generic fallback.
When it happens
Trigger: response.success is false when the research job completes or fails — invalid API key, credit exhaustion mid-job, rate limiting during the many underlying scrape/search calls, or all target pages failing to scrape.
Common situations: Long research jobs hitting credit limits before completion; Firecrawl service degradation during an expensive multi-step job; transient 429s not retried by the outer withRetry because the job already returned success:false.
Related errors
- Search failed: ${response.error || 'Unknown error'}
- ${extractResponse.error || 'Extraction failed'}
- ${response.error || 'LLMs.txt generation failed'}
- Token exchange failed: ${error}
- Google Directory groups.list failed (${response.status}): ${
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/a48f39bc300f3ac2.
Report an issue: GitHub.