{"record":{"id":"3c2812b4cfeba179","repo":"unclecode/crawl4ai","slug":"timeout-after-timeout-ms-waiting-for-selector-c","errorCode":null,"errorMessage":"Timeout after {timeout}ms waiting for selector '{css_selector}'","messagePattern":"Timeout after (.+?)ms waiting for selector '(.+?)'","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"warning","filePath":"crawl4ai/async_crawler_strategy.py","lineNumber":265,"sourceCode":"            timeout (float): Maximum time to wait in milliseconds\n\n        Returns:\n            None\n        \"\"\"\n        wait_for = wait_for.strip()\n\n        if wait_for.startswith(\"js:\"):\n            # Explicitly specified JavaScript\n            js_code = wait_for[3:].strip()\n            return await self.csp_compliant_wait(page, js_code, timeout)\n        elif wait_for.startswith(\"css:\"):\n            # Explicitly specified CSS selector\n            css_selector = wait_for[4:].strip()\n            try:\n                await page.wait_for_selector(css_selector, timeout=timeout)\n            except Error as e:\n                if \"Timeout\" in str(e):\n                    raise TimeoutError(\n                        f\"Timeout after {timeout}ms waiting for selector '{css_selector}'\"\n                    )\n                else:\n                    raise ValueError(f\"Invalid CSS selector: '{css_selector}'\")\n        else:\n            # Auto-detect based on content\n            if wait_for.startswith(\"()\") or wait_for.startswith(\"function\"):\n                # It's likely a JavaScript function\n                return await self.csp_compliant_wait(page, wait_for, timeout)\n            else:\n                # Assume it's a CSS selector first\n                try:\n                    await page.wait_for_selector(wait_for, timeout=timeout)\n                except Error as e:\n                    if \"Timeout\" in str(e):\n                        raise TimeoutError(\n                            f\"Timeout after {timeout}ms waiting for selector '{wait_for}'\"\n                        )","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/async_crawler_strategy.py#L247-L283","documentation":"ArtifactTooLarge is raised by write_artifact when a single artifact's byte length exceeds MAX_ARTIFACT_BYTES (env CRAWL4AI_MAX_ARTIFACT_BYTES, default 50 MiB). It is a hard per-item cap enforced before the store is even initialized, so oversized data never touches disk.","triggerScenarios":"Calling the artifact API (e.g. POST /artifact or an endpoint that stores screenshots/PDFs via write_artifact) with a body whose encoded size > 50 MiB (or your configured limit). len(data) is checked directly against the constant.","commonSituations":"Full-page screenshots or PDFs of very long pages; raising crawl quality/resolution so media blobs grow past the default; lowering CRAWL4AI_MAX_ARTIFACT_BYTES in a memory-tight deployment and forgetting old payloads exceed it.","solutions":["Reduce artifact size at the source (lower screenshot resolution/viewport, cap PDF page count, trim content)","Raise CRAWL4AI_ARTIFACT quota env is NOT the fix — raise CRAWL4AI_MAX_ARTIFACT_BYTES on the server if larger single artifacts are legitimate","Split the artifact into chunks below the per-item limit if the server limit must stay"],"exampleFix":"# server: raise per-artifact cap if large PDFs are expected\n# docker-compose.yml\nenvironment:\n  CRAWL4AI_MAX_ARTIFACT_BYTES: \"104857600\"  # 100 MiB","handlingStrategy":"validation","validationCode":"MAX_ARTIFACT_BYTES = int(os.environ.get(\"CRAWL4AI_MAX_ARTIFACT_BYTES\", 50 * 1024 * 1024))\ndef safe_artifact(data: bytes) -> bool:\n    return len(data) <= MAX_ARTIFACT_BYTES","typeGuard":null,"tryCatchPattern":"from artifacts import write_artifact, ArtifactTooLarge\ntry:\n    meta = write_artifact(\"screenshot\", data)\nexcept ArtifactTooLarge:\n    data = shrink(data)  # lower resolution / trim\n    meta = write_artifact(\"screenshot\", data)","preventionTips":["Check len(data) against CRAWL4AI_MAX_ARTIFACT_BYTES before calling","Cap screenshot viewport/resolution and PDF page counts for very long pages","Read the env var, do not hardcode 50 MiB — deployments differ"],"tags":["artifacts","size-limit","configuration"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}