firecrawl-known-pitfalls
A checklist of common Firecrawl mistakes to avoid in production code to prevent credit waste and data issues.
Install
mkdir -p .claude/skills/firecrawl-known-pitfalls && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/8057" && unzip -o skill.zip -d .claude/skills/firecrawl-known-pitfalls && rm skill.zipInstalls to .claude/skills/firecrawl-known-pitfalls
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Identify and avoid Firecrawl anti-patterns and common integration mistakes.Key capabilities
- →Identify unbounded crawl risks
- →Enforce output format specifications
- →Implement wait times for JavaScript-heavy pages
- →Optimize polling with exponential backoff
- →Validate extracted content with Zod
How it works
The skill provides code patterns to replace inefficient scraping methods with optimized, error-checked, and resource-aware implementations.
Inputs & outputs
When to use firecrawl-known-pitfalls
- →Reviewing Firecrawl implementation code
- →Preventing accidental credit depletion
- →Setting up scraping best practices
- →Onboarding new team members
About this skill
Firecrawl Known Pitfalls
Overview
Real gotchas from production Firecrawl integrations. Each pitfall includes the bad pattern, why it fails, and the correct approach. Use this as a code review checklist.
Pitfall 1: Unbounded Crawl (Credit Bomb)
import FirecrawlApp from "@mendable/firecrawl-js";
const firecrawl = new FirecrawlApp({
apiKey: process.env.FIRECRAWL_API_KEY!,
});
// BAD: no limit — a docs site with 50K pages burns your entire credit balance
await firecrawl.crawlUrl("https://docs.large-project.org");
// GOOD: always set limit, maxDepth, and path filters
await firecrawl.crawlUrl("https://docs.large-project.org", {
limit: 100,
maxDepth: 3,
includePaths: ["/api/*", "/guides/*"],
excludePaths: ["/changelog/*", "/blog/*"],
scrapeOptions: { formats: ["markdown"] },
});
Pitfall 2: Not Specifying Output Format
// BAD: default format may not include markdown
const result = await firecrawl.scrapeUrl("https://example.com");
console.log(result.markdown); // might be undefined!
// GOOD: explicitly request the format you need
const result = await firecrawl.scrapeUrl("https://example.com", {
formats: ["markdown"],
onlyMainContent: true,
});
console.log(result.markdown); // guaranteed present
Pitfall 3: Not Waiting for JS-Heavy Pages
// BAD: SPAs show loading state, not content
const result = await firecrawl.scrapeUrl("https://app.example.com/dashboard");
// result.markdown === "Loading..." or empty
// GOOD: wait for JS to render
const result = await firecrawl.scrapeUrl("https://app.example.com/dashboard", {
formats: ["markdown"],
waitFor: 5000, // wait 5s for JS rendering
onlyMainContent: true,
});
// BETTER: wait for a specific element
const result = await firecrawl.scrapeUrl("https://app.example.com/dashboard", {
formats: ["markdown"],
actions: [
{ type: "wait", selector: ".main-content" },
],
});
Pitfall 4: Wrong Package Name / Import
// BAD: these packages don't exist or are wrong
import FirecrawlApp from "firecrawl-js"; // wrong
import { FireCrawlClient } from "@firecrawl/sdk"; // wrong
// GOOD: the correct npm package
import FirecrawlApp from "@mendable/firecrawl-js"; // correct!
// Install: npm install @mendable/firecrawl-js
Pitfall 5: Polling Too Aggressively
// BAD: polling every 100ms wastes resources and may trigger rate limits
let status = await firecrawl.checkCrawlStatus(jobId);
while (status.status !== "completed") {
status = await firecrawl.checkCrawlStatus(jobId);
// No delay! Hammering the API
}
// GOOD: poll with backoff
let status = await firecrawl.checkCrawlStatus(jobId);
let interval = 2000;
while (status.status === "scraping") {
await new Promise(r => setTimeout(r, interval));
status = await firecrawl.checkCrawlStatus(jobId);
interval = Math.min(interval * 1.5, 30000); // back off to 30s
}
Pitfall 6: No Error Handling on Scrape
// BAD: assuming scrape always succeeds
const result = await firecrawl.scrapeUrl(url, { formats: ["markdown"] });
processContent(result.markdown!); // crashes if scrape failed
// GOOD: check result and handle failures
const result = await firecrawl.scrapeUrl(url, { formats: ["markdown"] });
if (!result.success || !result.markdown || result.markdown.length < 50) {
console.error(`Scrape failed or empty for ${url}`);
return null;
}
processContent(result.markdown);
Pitfall 7: Ignoring includePaths Start URL Match
// BAD: start URL doesn't match includePaths — crawl returns 0 pages
await firecrawl.crawlUrl("https://example.com/docs/intro", {
includePaths: ["/api/*"], // start URL /docs/intro doesn't match /api/*
limit: 50,
});
// GOOD: start URL must match (or omit) the include pattern
await firecrawl.crawlUrl("https://example.com", {
includePaths: ["/docs/*", "/api/*"], // start from root, filter paths
limit: 50,
});
Pitfall 8: Requesting Screenshots Unnecessarily
// BAD: screenshots are expensive (latency and bandwidth)
await firecrawl.scrapeUrl(url, {
formats: ["markdown", "html", "screenshot"],
// screenshot adds 5-10s to every scrape
});
// GOOD: only request screenshot when you actually need visual capture
await firecrawl.scrapeUrl(url, {
formats: ["markdown"], // just what you need
onlyMainContent: true,
});
Pitfall 9: Not Using Batch for Multiple URLs
// BAD: sequential scrapes (slow, N API calls)
const results = [];
for (const url of urls) {
results.push(await firecrawl.scrapeUrl(url, { formats: ["markdown"] }));
}
// GOOD: batch scrape (1 API call, internally parallel)
const batchResult = await firecrawl.batchScrapeUrls(urls, {
formats: ["markdown"],
onlyMainContent: true,
});
Pitfall 10: Not Validating Extracted Content
// BAD: trusting LLM extraction blindly
const result = await firecrawl.scrapeUrl(url, {
formats: ["extract"],
extract: { schema: productSchema },
});
await db.insert(result.extract); // could be null, malformed, or hallucinated
// GOOD: validate with Zod before persisting
import { z } from "zod";
const ProductSchema = z.object({
name: z.string().min(1),
price: z.number().positive(),
});
const parsed = ProductSchema.safeParse(result.extract);
if (parsed.success) {
await db.insert(parsed.data);
} else {
console.error("Extraction validation failed:", parsed.error.issues);
}
Code Review Checklist
- All
crawlUrlcalls havelimitset -
formatsexplicitly specified (never rely on defaults) -
waitFororactionsused for SPAs - Import is
@mendable/firecrawl-js - Async crawl polls with backoff, not tight loop
- Scrape result checked for success and content length
- Batch scrape used for multiple known URLs
- Extract results validated before persistence
- Error handling for 429, 402, and empty content
Resources
Next Steps
For reference architecture, see firecrawl-reference-architecture.
When not to use it
- →When scraping small, static sites where performance is not a concern
- →When using deprecated or incorrect package names
Limitations
- →Requires explicit configuration of limits and formats
- →Batch scraping is necessary for multiple URLs to avoid sequential latency
How it compares
This approach replaces manual, error-prone scraping scripts with a checklist-driven implementation that prevents common production failures.
Compared to similar skills
firecrawl-known-pitfalls side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| firecrawl-known-pitfalls (this skill) | 0 | 26d | Review | Intermediate |
| schema-markup | 10 | 6mo | No flags | Intermediate |
| nextjs-developer | 328 | 2mo | No flags | Advanced |
| deepwiki-rs | 25 | 9mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
schema-markup
davila7
When the user wants to add, fix, or optimize schema markup and structured data on their site. Also use when the user mentions "schema markup," "structured data," "JSON-LD," "rich snippets," "schema.org," "FAQ schema," "product schema," "review schema," or "breadcrumb schema." For broader SEO issues, see seo-audit.
nextjs-developer
zenobi-us
Expert Next.js developer mastering Next.js 14+ with App Router and full-stack features. Specializes in server components, server actions, performance optimization, and production deployment with focus on building fast, SEO-friendly applications.
deepwiki-rs
sopaco
AI-powered Rust documentation generation engine for comprehensive codebase analysis, C4 architecture diagrams, and automated technical documentation. Use when Claude needs to analyze source code, understand software architecture, generate technical specs, or create professional documentation from any programming language.
writing-registry-meta
siriwatknp
Use this skill when writing meta file for MUI Treasury registry.
markdown-to-html
github
Convert Markdown files to HTML similar to `marked.js`, `pandoc`, `gomarkdown/markdown`, or similar tools; or writing custom script to convert markdown to html and/or working on web template systems like `jekyll/jekyll`, `gohugoio/hugo`, or similar web templating systems that utilize markdown documents, converting them to html. Use when asked to "convert markdown to html", "transform md to html", "render markdown", "generate html from markdown", or when working with .md files and/or web a templating system that converts markdown to HTML output. Supports CLI and Node.js workflows with GFM, CommonMark, and standard Markdown flavors.
coding-standards
affaan-m
适用于TypeScript、JavaScript、React和Node.js开发的通用编码标准、最佳实践和模式。