Skip to main content

Overview

Argument Cartographer integrates with multiple external APIs. This guide helps you diagnose and resolve API-related errors based on actual error handling in the codebase.

Firecrawl API Errors

Error: “Firecrawl API key not configured”

Full error message:
Firecrawl API key not configured. Please set FIRECRAWL_API_KEY in .env
Location: src/ai/tools/web-search.ts:58, src/ai/tools/web-scraper.ts:25 Validation code:
if (!firecrawlKey || firecrawlKey === 'YOUR_API_KEY_HERE') {
  throw new Error('Firecrawl API key not configured. Please set FIRECRAWL_API_KEY in .env');
}
1

Verify Environment Variable

Check that FIRECRAWL_API_KEY is set:
.env
FIRECRAWL_API_KEY=fc-your-actual-key
Don’t use placeholder values like YOUR_API_KEY_HERE — they’re explicitly rejected.
2

Get Valid API Key

  1. Go to Firecrawl
  2. Sign up or log in
  3. Navigate to API Keys section
  4. Generate a new key
  5. Copy the key (starts with fc-)
3

Update Vercel Environment Variables

If deploying on Vercel:
  1. Go to Project SettingsEnvironment Variables
  2. Add or update FIRECRAWL_API_KEY
  3. Redeploy the application

Error: “Firecrawl Search Failed”

Symptom: Console shows [Firecrawl Search] Failed: 402 or [Firecrawl Search] Failed: 429 Status codes:
402
Insufficient Credits
Your Firecrawl account has run out of credits.Solution: Add credits to your Firecrawl account or upgrade plan.
429
Rate Limit Exceeded
Too many requests in a short time period.Solution:
  • Implement rate limiting in your application
  • Upgrade to higher tier for increased limits
  • Wait and retry after cooldown period
403
Forbidden
API key is invalid or revoked.Solution: Generate a new API key.
Automatic fallback behavior:
// From web-search.ts:83-87
if (!response.ok) {
  console.warn(`[Firecrawl Search] Failed: ${response.status}`);
  // Fallback to general search without site filter
  return searchWebGeneral(query, firecrawlKey);
}
The application automatically:
  1. Tries targeted search with trusted news outlets
  2. Falls back to general search if targeted search fails
  3. Falls back to search snippets if scraping fails
  4. Enters limited analysis mode if all APIs fail
These fallbacks ensure the application continues to function even when Firecrawl credits are depleted.

Error: “Content too short”

Console output: [Firecrawl] Content too short for {url} Cause: Scraped markdown is less than 100 characters. Validation code:
// From web-scraper.ts:53-56
if (!markdown || markdown.length < 100) {
  console.warn(`[Firecrawl] Content too short for ${url}`);
  return null;
}
Common reasons:
  • URL is a login page or paywall
  • Content is behind JavaScript rendering
  • Website blocks Firecrawl’s user agent
  • URL returns 404 or redirect
Solution: The application automatically skips failed URLs and continues with successful ones:
// From web-scraper.ts:104-110
for (const result of scrapeResults) {
  if (result.content) {
    results.push({ url: result.url, content: result.content, source: result.source });
  }
}

Twitter API Errors

Error: “TWITTER_BEARER_TOKEN is not configured”

Full error message:
TWITTER_BEARER_TOKEN is not configured. Please add it to your .env file.
Location: src/ai/tools/twitter-search.ts:49 Validation code:
if (!bearerToken || bearerToken === 'YOUR_BEARER_TOKEN_HERE') {
  throw new Error('TWITTER_BEARER_TOKEN is not configured. Please add it to your .env file.');
}
1

Get Twitter API Access

  1. Go to Twitter Developer Portal
  2. Create a new project or select existing
  3. Create an app within the project
  4. Navigate to app settings
2

Generate Bearer Token

  1. Go to Keys and tokens tab
  2. Under Authentication Tokens, generate Bearer Token
  3. Copy the token immediately (it won’t be shown again)
  4. Store securely in .env file
3

Configure Token

.env
TWITTER_BEARER_TOKEN=AAAAAAAAAAAAAAAAAAAAABearerTokenHere

Error: Twitter API 401 Unauthorized

Symptom: Twitter API request failed with status 401 Causes:
Token is incorrect, expired, or revoked.Solution:
  1. Regenerate bearer token in Twitter Developer Portal
  2. Update environment variable
  3. Redeploy application
Check the request format:
// Correct format (from twitter-search.ts:66-72)
const response = await fetch(
  `https://api.twitter.com/2/tweets/search/recent?${searchParams.toString()}`,
  {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${bearerToken}`,  // Must be formatted correctly
      'Content-Type': 'application/json',
    },
  }
);
Verify your Twitter app has required permissions:
  1. Go to Developer Portal → Your App → Settings
  2. Check App permissions
  3. Must have at least Read access
  4. Save changes and regenerate tokens if changed

Error: Twitter API 429 Rate Limit

Symptom: Twitter API request failed with status 429 Twitter API v2 rate limits:
tweets/search/recent
endpoint
Rate limit: 180 requests per 15-minute window (per user)Application usage:
  • 1 request per argument analysis
  • Max 20 tweets returned per request
Monitoring rate limits:
// Check response headers for rate limit info
const remaining = response.headers.get('x-rate-limit-remaining');
const reset = response.headers.get('x-rate-limit-reset');

console.log(`Twitter API: ${remaining} requests remaining`);
console.log(`Resets at: ${new Date(reset * 1000).toISOString()}`);
Solutions:
1

Implement Caching

Cache Twitter search results by query:
const cache = new Map<string, { tweets: Tweet[], timestamp: number }>();
const CACHE_TTL = 15 * 60 * 1000; // 15 minutes

function getCachedTweets(query: string) {
  const cached = cache.get(query);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.tweets;
  }
  return null;
}
2

Handle Rate Limit Gracefully

The application already handles this as a non-fatal error:
// From generate-argument-blueprint.ts:337-339
catch (error: any) {
  console.error("Twitter search failed, continuing. Error:", error.message);
}
Analysis continues without social pulse data.
3

Upgrade API Tier

For high-volume usage:
  • Basic tier: 500,000 tweets/month, $100/month
  • Pro tier: Higher limits, custom pricing

No Tweets Found (Empty Result)

Symptom: Twitter search returns empty array [] This is not an error — it’s a valid response when no tweets match the query. Validation code:
// From twitter-search.ts:86-89
if (tweetsData.length === 0) {
  // No tweets found is a valid (empty) result, not an error.
  return [];
}
Common reasons:
  • Topic is too niche or recent
  • Search query filters out all results
  • Language filter (lang:en) excludes relevant tweets
  • Query uses operators that are too restrictive
The application query format:
// From twitter-search.ts:57
'query': `${input.query} lang:en -is:retweet`
Optimization: If getting empty results, try broader queries or remove language filter.

Google Gemini API Errors

Model Not Available

Symptom: “Model ‘gemini-1.5-pro’ not available” or 404 errors. Causes:
  • API key doesn’t have access to Gemini 1.5 Pro
  • Model name is incorrect
  • Region restrictions
Solution:
1

Verify Model Access

  1. Go to Google AI Studio
  2. Test your API key with Gemini 1.5 Pro
  3. Ensure your project has access to the model
2

Check Model Name

The application uses:
model: 'gemini-1.5-pro'
Verify this matches Google’s current model naming.
3

Enable Required APIs

In Google Cloud Console:
  1. Navigate to APIs & Services
  2. Enable Generative Language API
  3. Wait a few minutes for propagation

Safety Filter Triggered

Symptom: AI refuses to respond or returns empty content. Error message:
The AI model refused to respond due to safety filters.
Gemini safety categories:
  • Hate speech
  • Sexually explicit content
  • Harassment
  • Dangerous content
Solutions:
  1. Rephrase input: Avoid potentially sensitive topics or rephrase neutrally
  2. Review source content: Scraped articles may contain filtered content
  3. Adjust safety settings: Configure in Genkit AI config (use with caution)
Lowering safety filters may violate Google’s acceptable use policy. Only adjust for legitimate research purposes.

Token Limit Exceeded

Symptom: “Input tokens exceed maximum context length” Gemini 1.5 Pro limits:
  • Context window: 1 million tokens (~700,000 words)
  • Output limit: 8,192 tokens
Application safeguards:
// From web-scraper.ts:60
return markdown.substring(0, 20000);  // Limit per source

// From generate-argument-blueprint.ts:231
${doc.content.substring(0, 12000)}  // Additional truncation
If still exceeding limits:
  1. Reduce number of sources:
    if (urlsToScrape.length >= 8) break; // Reduce from 8 to 5
    
  2. Implement chunking: Split large analyses into multiple AI calls
  3. Summarize sources first: Use a separate flow to summarize each source before main analysis

Error Response Patterns

Standard Error Object

All API errors follow this pattern:
interface APIError {
  message: string;      // Human-readable error
  code?: string;        // Error code (e.g., 'RATE_LIMIT_EXCEEDED')
  status?: number;      // HTTP status code
  details?: any;        // Additional context
}

Logging Best Practices

The application logs errors with context:
// From generate-argument-blueprint.ts:290
console.error("Failed to parse JSON from AI response. Raw Text:", rawText);

// From twitter-search.ts:76
console.error('Error from Twitter API:', errorBody);

// From web-search.ts:115
console.warn(`[Firecrawl Search] Error: ${error.message}`);
All errors are logged to console. Check Vercel function logs for detailed error traces.

Testing API Integrations

Test Firecrawl

curl -X POST "https://api.firecrawl.dev/v1/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "artificial intelligence",
    "limit": 5
  }'
Expected response: Array of search results with title, url, description.

Test Twitter API

curl "https://api.twitter.com/2/tweets/search/recent?query=AI%20lang:en&max_results=10" \
  -H "Authorization: Bearer YOUR_BEARER_TOKEN"
Expected response: JSON with data array containing tweet objects.

Test Google Gemini

curl -X POST "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-pro:generateContent?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{
      "parts": [{"text": "Explain quantum computing in one sentence."}]
    }]
  }'
Expected response: Generated text in candidates[0].content.parts[0].text.

Debugging Checklist

1

Verify All API Keys

# Check environment variables are set
echo $GOOGLE_GENAI_API_KEY | cut -c1-10
echo $FIRECRAWL_API_KEY | cut -c1-10
echo $TWITTER_BEARER_TOKEN | cut -c1-10
2

Test Each API Independently

Use the curl commands above to verify each API works outside your application.
3

Check Vercel Environment Variables

Ensure variables are:
  • Added to correct environment (Production/Preview)
  • Spelled exactly as expected
  • Not containing extra spaces or quotes
4

Monitor API Usage

  • Firecrawl: Check dashboard for credit balance
  • Twitter: Monitor rate limit headers
  • Google: Review Cloud Console quotas
5

Review Error Logs

Vercel Dashboard → Deployments → Function LogsLook for:
  • Stack traces
  • Console warnings
  • Error payloads

Next Steps

Common Issues

General troubleshooting guide

Performance

Optimize API call performance

Environment Variables

Complete environment variable reference

Firebase Setup

Configure Firebase integration

Build docs developers (and LLMs) love