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

  1. 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
  2. Check server logs for the full traceback (the handler logs/monitors the exception before re-raising) and fix the underlying fault
  3. 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
  4. 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

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


AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14). Data as JSON: /api/errors/da0cc50cb9583b8a. Report an issue: GitHub.