{"record":{"id":"f2a1027817ae1ea3","repo":"unclecode/crawl4ai","slug":"server-error-e-response-status-code-error-msg","errorCode":null,"errorMessage":"Server error {e.response.status_code}: {error_msg}","messagePattern":"Server error (.+?): (.+?)","errorType":"exception","errorClass":"RequestError","httpStatus":null,"severity":"error","filePath":"crawl4ai/docker_client.py","lineNumber":124,"sourceCode":"\n        return request_data\n\n    async def _request(self, method: str, endpoint: str, **kwargs) -> httpx.Response:\n        \"\"\"Make an HTTP request with error handling.\"\"\"\n        url = urljoin(self.base_url, endpoint)\n        try:\n            response = await self._http_client.request(method, url, **kwargs)\n            response.raise_for_status()\n            return response\n        except httpx.TimeoutException as e:\n            raise ConnectionError(f\"Request timed out: {str(e)}\")\n        except httpx.RequestError as e:\n            raise ConnectionError(f\"Failed to connect: {str(e)}\")\n        except httpx.HTTPStatusError as e:\n            error_msg = (e.response.json().get(\"detail\", str(e)) \n                        if \"application/json\" in e.response.headers.get(\"content-type\", \"\") \n                        else str(e))\n            raise RequestError(f\"Server error {e.response.status_code}: {error_msg}\")\n\n    async def crawl(\n        self,\n        urls: List[str],\n        browser_config: Optional[BrowserConfig] = None,\n        crawler_config: Optional[CrawlerRunConfig] = None,\n        hooks: Optional[Union[Dict[str, Callable], Dict[str, str]]] = None,\n        hooks_timeout: int = 30\n    ) -> Union[CrawlResult, List[CrawlResult], AsyncGenerator[CrawlResult, None]]:\n        \"\"\"\n        Execute a crawl operation.\n\n        Args:\n            urls: List of URLs to crawl\n            browser_config: Browser configuration\n            crawler_config: Crawler configuration\n            hooks: Optional hooks - can be either:\n                   - Dict[str, Callable]: Function objects that will be converted to strings","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/docker_client.py#L106-L142","documentation":"Raised by Crawl4aiDockerClient._request when the server returns a non-2xx status (raise_for_status triggers httpx.HTTPStatusError). The client extracts the 'detail' field from a JSON error body if present, otherwise uses the raw status line, and raises a RequestError('Server error {status}: {detail}'). This is the server explicitly rejecting the request.","triggerScenarios":"POSTing to /crawl with browser_config/crawler_config payloads the server cannot validate (e.g. 422 with detail listing invalid fields); calling an endpoint without prior authentication resulting in 401; 500 from a server-side crawl crash; version mismatch between client and server API.","commonSituations":"Passing configs with fields unknown to the server's schema (client newer/older than the Docker image); forgetting to call authenticate() so the Authorization header is missing; the server running an older image lacking newer endpoints like /schema.","solutions":["Read the detail text — FastAPI 422 detail names the exact invalid config field","Call get_schema() (when available) to see which config keys the server version accepts","Ensure authenticate() was called before making requests","Pin the Docker server image to the same version as the installed crawl4ai client"],"exampleFix":"// before\nresults = await client.crawl(urls, browser_config=BrowserConfig(some_new_field=1))\n# Server error 422: {'detail': [...]}\n\n// after\nschema = await client.get_schema()  # inspect accepted fields\nresults = await client.crawl(urls, browser_config=BrowserConfig(headless=True))","handlingStrategy":"try-catch","validationCode":"schema = await client.get_schema()  # accepted fields per config type\n# intersect your config kwargs with schema before sending\nallowed = schema[\"GET\"][\"/crawl\"][\"parameters\"][\"browser_config\"]\nbc_kwargs = {k: v for k, v in my_kwargs.items() if k in allowed}","typeGuard":null,"tryCatchPattern":"try:\n    results = await client.crawl(urls, browser_config=b, crawler_config=c)\nexcept RequestError as e:\n    status = str(e).split(':')[0].replace('Server error ', '')\n    if status == '401':\n        await client.authenticate(email)  # re-auth then retry once\n    elif status == '422':\n        log.error(\"config rejected: %s\", e)  # fix fields named in detail\n    else:\n        raise","preventionTips":["Authenticate before any request","Fetch and honor the server schema when sending complex configs","Keep client and server image versions in lockstep"],"tags":["docker-client","http-status","validation"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}