{"record":{"id":"6632343ba9ce90b2","repo":"unclecode/crawl4ai","slug":"deep-crawling-with-stream-currently-supports-exact","errorCode":null,"errorMessage":"Deep crawling with stream currently supports exactly one URL per request. Received {len(urls)} URLs.","messagePattern":"Deep crawling with stream currently supports exactly one URL per request\\. Received (.+?) URLs\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"deploy/docker/api.py","lineNumber":881,"sourceCode":"    try:\n        # SSRF guard: validate every seed URL's destination before fetching,\n        # mirroring handle_crawl_request. The streaming path previously skipped\n        # this, leaving /crawl/stream (and /crawl with stream=true) unguarded.\n        urls = _normalize_and_validate_seeds(urls)\n        browser_config = BrowserConfig.load(browser_config, provenance=Provenance.UNTRUSTED)\n        # browser_config.verbose = True # Set to False or remove for production stress testing\n        browser_config.verbose = False\n        from egress_broker import enforce_egress\n        enforce_egress(browser_config)\n        crawler_config = CrawlerRunConfig.load(crawler_config, provenance=Provenance.UNTRUSTED)\n        from governor import clamp_deep_crawl\n        clamp_deep_crawl(crawler_config)\n        crawler_config.scraping_strategy = LXMLWebScrapingStrategy()\n        crawler_config.stream = True\n\n        # Deep crawl streaming supports exactly one start URL\n        if crawler_config.deep_crawl_strategy is not None and len(urls) != 1:\n            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail=(\n                    \"Deep crawling with stream currently supports exactly one URL per request. \"\n                    f\"Received {len(urls)} URLs.\"\n                ),\n            )\n\n        from crawler_pool import get_crawler, release_crawler\n        crawler = await get_crawler(browser_config)\n\n        # Attach declarative hooks if provided\n        if hooks_config:\n            hooks_status = _attach_declarative_hooks(crawler, hooks_config)\n            logger.info(f\"Hooks attachment status for streaming: {hooks_status['status']}\")\n            hooks_info = {'status': hooks_status}\n\n        # Deep crawl with single URL: use arun() which returns an async generator\n        # mirroring the Python library's streaming behavior","sourceCodeStart":863,"sourceCodeEnd":899,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/api.py#L863-L899","documentation":"Error \"Deep crawling with stream currently supports exactly one URL per request. Received {len(urls)} URLs.\" thrown in unclecode/crawl4ai.","triggerScenarios":"Thrown at deploy/docker/api.py:881 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Send exactly one URL per request when using deep crawling with stream=true.","Disable streaming or split multiple URLs into separate requests."],"exampleFix":"POST /crawl {\"urls\": [\"https://example.com\"], \"deep_crawl\": true, \"stream\": true}","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}