{"record":{"id":"5509eeabbf61b35d","repo":"unclecode/crawl4ai","slug":"execute-js-endpoint-is-disabled-set-crawl4ai-exec","errorCode":null,"errorMessage":"execute_js endpoint is disabled. Set CRAWL4AI_EXECUTE_JS_ENABLED=true to enable.","messagePattern":"execute_js endpoint is disabled\\. Set CRAWL4AI_EXECUTE_JS_ENABLED=true to enable\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"warning","filePath":"deploy/docker/server.py","lineNumber":786,"sourceCode":"            response_headers: Optional[dict] = None\n            status_code: Optional[int] = None\n            ssl_certificate: Optional[SSLCertificate] = None\n            dispatch_result: Optional[DispatchResult] = None\n            redirected_url: Optional[str] = None\n            network_requests: Optional[List[Dict[str, Any]]] = None\n            console_messages: Optional[List[Dict[str, Any]]] = None\n\n        class MarkdownGenerationResult(BaseModel):\n            raw_markdown: str\n            markdown_with_citations: str\n            references_markdown: str\n            fit_markdown: Optional[str] = None\n            fit_html: Optional[str] = None\n        ```\n\n    \"\"\"\n    if not EXECUTE_JS_ENABLED:\n        raise HTTPException(403, \"execute_js endpoint is disabled. Set CRAWL4AI_EXECUTE_JS_ENABLED=true to enable.\")\n    validate_url_scheme(body.url)\n    # Block SSRF: reject internal/private IPs\n    try:\n        validate_webhook_url(body.url)  # reuse SSRF blocklist\n    except ValueError as e:\n        raise HTTPException(400, str(e))\n    crawler = None\n    try:\n        cfg = CrawlerRunConfig(js_code=body.scripts)\n        crawler = await get_crawler(get_default_browser_config())\n        results = await crawler.arun(url=body.url, config=cfg)\n        if not results[0].success:\n            raise HTTPException(500, detail=results[0].error_message or \"Crawl failed\")\n        data = results[0].model_dump()\n        return JSONResponse(data)\n    except Exception as e:\n        raise HTTPException(500, detail=str(e))\n    finally:","sourceCodeStart":768,"sourceCodeEnd":804,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/server.py#L768-L804","documentation":"A 403 from POST /execute_js: the endpoint is compile-time gated by the EXECUTE_JS_ENABLED flag (env CRAWL4AI_EXECUTE_JS_ENABLED) and is disabled by default, because letting clients run arbitrary JavaScript in the server's browser is dangerous. No request content can bypass this; only the environment variable enables it.","triggerScenarios":"POST /execute_js against any deployment where CRAWL4AI_EXECUTE_JS_ENABLED is not set to 'true'. The check happens before URL validation, SSRF checks, and token-dependent crawl logic, so every call fails identically.","commonSituations":"New deployments using default env; upgrading the server to a version that added the kill switch; CI environments that never set the flag; MCP tool discovery listing execute_js even though it's off.","solutions":["Set CRAWL4AI_EXECUTE_JS_ENABLED=true in the container environment and restart, if you accept the risk of running client-supplied JS.","If you don't need JS execution, use /crawl with js_code in crawler_config if that path is enabled, or other endpoints.","Verify the flag took effect: docker inspect the env or check server startup logs."],"exampleFix":"# before\ndocker run ... crawl4ai-server\n# after\ndocker run -e CRAWL4AI_EXECUTE_JS_ENABLED=true ... crawl4ai-server","handlingStrategy":"validation","validationCode":"import requests\n\ndef execute_js_available(base: str, hdrs: dict) -> bool:\n    # cheap probe: the flag check runs before auth-heavy work\n    r = requests.post(f'{base}/execute_js', json={'url': 'https://example.com', 'scripts': []}, headers=hdrs)\n    return r.status_code != 403 or 'disabled' not in r.text","typeGuard":null,"tryCatchPattern":"resp = requests.post(f'{BASE}/execute_js', json=body, headers=hdrs)\nif resp.status_code == 403 and 'CRAWL4AI_EXECUTE_JS_ENABLED' in resp.text:\n    raise RuntimeError('execute_js disabled server-side; set CRAWL4AI_EXECUTE_JS_ENABLED=true or use another endpoint')","preventionTips":["Probe once at client startup and cache whether execute_js is enabled.","Keep js_code paths optional in your pipeline with a graceful non-JS fallback.","Never assume new endpoints are on by default — this one is a security-gated opt-in."],"tags":["execute-js","feature-flag","http-403","security","environment"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}