Describe the Bug
The Rust SDK's crawl, batch scrape, and agent status/cancel calls report a bare HTTP error 404: 404 (or whatever status code) instead of the server's actual error message. handle_response in client.rs decided how to interpret a response by checking whether the caller's internal action label contained the words "status" or "cancel", not by checking the response body's own success field. Any call using one of those labels skipped the real check and force-parsed the body as a success type, so a genuine error body like {"success":false,"error":"Job not found"} failed to deserialize and the real message was discarded before it ever reached the caller. This affected get_crawl_status, cancel_crawl, get_batch_scrape_status, get_agent_status, and cancel_agent.
To Reproduce
Steps to reproduce the issue:
- Start a self-hosted Firecrawl instance:
docker compose up -d --build nuq-postgres api from the repo root (no .env needed).
- In a Rust project depending on
firecrawl 2.19.0, create a client and call get_crawl_status (or cancel_crawl) with a job ID that doesn't exist:
let client = Client::new_selfhosted("http://localhost:3002", None::<&str>)?;
let err = client.get_crawl_status("00000000-0000-0000-0000-000000000000").await.unwrap_err();
println!("{err}");
- Observe the error printed to stdout.
- Compare against the raw server response for the same request:
curl -i -X DELETE http://localhost:3002/v2/crawl/00000000-0000-0000-0000-000000000000, which correctly returns {"success":false,"error":"Job not found"}.
Expected Behavior
The error returned by the SDK should contain the server's actual message, e.g. crawl status 00000000-0000-0000-0000-000000000000 failed: Job not found, matching what the API itself sent.
Screenshots
Not applicable — command line output only.
Environment (please complete the following information):
- OS: macOS 26.4.1 (Apple Silicon)
- Deployment Type: Self-hosted (default
docker-compose.yaml, USE_DB_AUTHENTICATION=false)
- Firecrawl Version:
main branch, Rust SDK (firecrawl crate) 2.19.0
- Node.js Version: v22.23.2 (inside the API container)
Logs
Error: HttpRequestFailed("crawl status 00000000-0000-0000-0000-000000000000", 404, "404")
No error is logged server-side; the API responds correctly with a 200/404 and a proper JSON error body. The loss happens entirely client-side in the Rust SDK.
Additional Context
Root cause and fix are in PR #4588. The bug is in apps/rust-sdk/src/client.rs's handle_response, which gated the success:false check on a substring match against the action label instead of the response body:
| File : line |
Action string |
crawl.rs:230 |
"crawl status {id}" |
crawl.rs:378 |
"cancel crawl" |
batch_scrape.rs:209 |
"batch scrape status {id}" |
agent.rs:555 |
"agent status {id}" |
agent.rs:828 |
"cancel agent {id}" |
The fix also surfaced and resolved two related gaps: apps/api's crawlCancelController was missing success on several of its own responses, and CrawlJob/BatchScrapeJob had no field to carry a failure reason when a crawl fails at kickoff, which briefly reintroduced message loss for that specific case until fixed.
Describe the Bug
The Rust SDK's crawl, batch scrape, and agent status/cancel calls report a bare
HTTP error 404: 404(or whatever status code) instead of the server's actual error message.handle_responseinclient.rsdecided how to interpret a response by checking whether the caller's internal action label contained the words "status" or "cancel", not by checking the response body's ownsuccessfield. Any call using one of those labels skipped the real check and force-parsed the body as a success type, so a genuine error body like{"success":false,"error":"Job not found"}failed to deserialize and the real message was discarded before it ever reached the caller. This affectedget_crawl_status,cancel_crawl,get_batch_scrape_status,get_agent_status, andcancel_agent.To Reproduce
Steps to reproduce the issue:
docker compose up -d --build nuq-postgres apifrom the repo root (no.envneeded).firecrawl2.19.0, create a client and callget_crawl_status(orcancel_crawl) with a job ID that doesn't exist:curl -i -X DELETE http://localhost:3002/v2/crawl/00000000-0000-0000-0000-000000000000, which correctly returns{"success":false,"error":"Job not found"}.Expected Behavior
The error returned by the SDK should contain the server's actual message, e.g.
crawl status 00000000-0000-0000-0000-000000000000 failed: Job not found, matching what the API itself sent.Screenshots
Not applicable — command line output only.
Environment (please complete the following information):
docker-compose.yaml,USE_DB_AUTHENTICATION=false)mainbranch, Rust SDK (firecrawlcrate) 2.19.0Logs
No error is logged server-side; the API responds correctly with a 200/404 and a proper JSON error body. The loss happens entirely client-side in the Rust SDK.
Additional Context
Root cause and fix are in PR #4588. The bug is in
apps/rust-sdk/src/client.rs'shandle_response, which gated thesuccess:falsecheck on a substring match against the action label instead of the response body:crawl.rs:230"crawl status {id}"crawl.rs:378"cancel crawl"batch_scrape.rs:209"batch scrape status {id}"agent.rs:555"agent status {id}"agent.rs:828"cancel agent {id}"The fix also surfaced and resolved two related gaps:
apps/api'scrawlCancelControllerwas missingsuccesson several of its own responses, andCrawlJob/BatchScrapeJobhad no field to carry a failure reason when a crawl fails at kickoff, which briefly reintroduced message loss for that specific case until fixed.