unclecode/crawl4ai · error · Error
Error evaluating condition: ${{error.message}}
Error message
Error evaluating condition: ${{error.message}} What it means
Raised as an HTTP 500 from the crawl endpoint's catch-all handler when any unexpected exception escapes a (non-streaming) crawl request. The response body is a JSON-encoded string carrying the original error message plus the server's memory delta and peak RSS for that request. It is a last-resort signal: the real cause is whatever `e` is, so check the server logs for the logged exception and the `error` field for the underlying message.
Source
Thrown at crawl4ai/async_crawler_strategy.py:330
Raises:
RuntimeError: If there's an error evaluating the condition
"""
wrapper_js = f"""
async () => {{
const userFunction = {user_wait_function};
const startTime = Date.now();
try {{
while (true) {{
if (await userFunction()) {{
return true;
}}
if (Date.now() - startTime > {timeout}) {{
return false; // Return false instead of throwing
}}
await new Promise(resolve => setTimeout(resolve, 100));
}}
}} catch (error) {{
throw new Error(`Error evaluating condition: ${{error.message}}`);
}}
}}
"""
try:
result = await self.adapter.evaluate(page, wrapper_js)
return result
except Exception as e:
if "Error evaluating condition" in str(e):
raise RuntimeError(f"Failed to evaluate wait condition: {str(e)}")
# For timeout or other cases, just return False
return False
async def process_iframes(self, page):
"""
Process iframes on a page. This function will extract the content of each iframe and replace it with a div containing the extracted content.
Args:View on GitHub (pinned to 7e80152142)
Solutions
- Read the `error` field in the 500 detail — it is the message of the underlying exception; treat this 500 as a wrapper, not the root cause
- Check server logs for the full traceback (the handler logs/monitors the exception before re-raising) and fix the underlying fault
- If server_memory_delta_mb is large, reduce parallelism / page count per browser or cap page resources in crawler_config to avoid OOM-driven crashes
- Retry with exponential backoff for transient site/network failures; if it reproduces on one URL, crawl that URL in isolation to get a cleaner stack trace
Example fix
# before
resp = await client.post("/crawl", json=payload)
resp.raise_for_status()
# after
resp = await client.post("/crawl", json=payload)
if resp.status_code == 500:
detail = json.loads(resp.json()["detail"])
logging.error("crawl failed: %s (server mem delta %.1f MB)",
detail["error"], detail.get("server_memory_delta_mb", 0))
resp.raise_for_status() Defensive patterns
Strategy: retry
Validate before calling
# validate payload shape client-side to avoid avoidable 500s
import json
def valid_crawl_payload(p):
assert isinstance(p.get("urls"), list) and p["urls"], "urls required"
assert all(u.lower().startswith(("http://", "https://")) for u in p["urls"])
return True Try / catch
try:
resp = await client.post("/crawl", json=payload)
resp.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 500:
detail = json.loads(e.response.json()["detail"])
log.error("crawl failed: %s", detail["error"]) # real cause
raise Prevention
- Treat the 500 detail's `error` field as the root cause; this handler is only a wrapper
- Cap concurrency and per-page resources so server_memory_delta_mb stays small
- Retry transient 500s with exponential backoff and jitter, bounded attempts
When it happens
Trigger: POSTing a crawl request to /crawl (or a similar non-stream endpoint) whose processing throws an unhandled exception after the browser pool is engaged — e.g. target page render crashes, Playwright browser dies mid-run, or an unexpected library error inside crawler execution. The endpoint wraps it as HTTPException(500, json.dumps({error, server_memory_delta_mb, server_peak_memory_mb})).
Common situations: Crawling pages that exhaust browser memory (large delta/peak values in the detail are the tell), incompatible Playwright/Chromium versions after an image upgrade, a target site returning payloads that break the scraping strategy, or transient network failures inside the crawl itself.
Related errors
- Crawl failed
- Invalid hook type: {hook_type}
- Unknown strategy: {strategy_name}
- Memory usage exceeded threshold for {self.memory_wait_timeou
- Crawl failed: {result_data.get('msg', 'Unknown error')}
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/da0cc50cb9583b8a.
Report an issue: GitHub.