{"record":{"id":"eea43b87eae2802e","repo":"unclecode/crawl4ai","slug":"browser-with-sig-req-sig-not-found","errorCode":null,"errorMessage":"Browser with sig={req.sig} not found","messagePattern":"Browser with sig=(.+?) not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"deploy/docker/monitor_routes.py","lineNumber":224,"sourceCode":"                if sig.startswith(req.sig):\n                    target_sig = sig\n                    pool_type = \"hot\"\n                    break\n\n            # Check cold pool\n            if not target_sig:\n                for sig in COLD_POOL.keys():\n                    if sig.startswith(req.sig):\n                        target_sig = sig\n                        pool_type = \"cold\"\n                        break\n\n            # Check if trying to kill permanent\n            if DEFAULT_CONFIG_SIG and DEFAULT_CONFIG_SIG.startswith(req.sig):\n                raise HTTPException(403, \"Cannot kill permanent browser. Use restart instead.\")\n\n            if not target_sig:\n                raise HTTPException(404, f\"Browser with sig={req.sig} not found\")\n\n            # Warn if there are active requests (browser might be in use)\n            monitor = get_monitor()\n            active_count = len(monitor.get_active_requests())\n            if active_count > 0:\n                logger.warning(f\"Killing browser {target_sig[:8]} while {active_count} requests are active - may cause failures\")\n\n            # Kill the browser\n            if pool_type == \"hot\":\n                browser = HOT_POOL.pop(target_sig)\n            else:\n                browser = COLD_POOL.pop(target_sig)\n\n            with suppress(Exception):\n                await browser.close()\n\n            LAST_USED.pop(target_sig, None)\n            USAGE_COUNT.pop(target_sig, None)","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/monitor_routes.py#L206-L242","documentation":"An explicit 404 raised by POST /monitor/actions/kill_browser when the provided signature prefix matches no browser in the hot pool, the cold pool, or the permanent default. Signatures are looked up by prefix match (sig.startswith(req.sig)), so this means the prefix matches nothing - the browser already exited, was killed, or the prefix is wrong.","triggerScenarios":"Calling kill_browser with a stale sig from an older /monitor/browsers listing (browser already reaped by janitor), a prefix shorter/longer than any current signature, or a typo; also two kills of the same browser where the first succeeded.","commonSituations":"Dashboard list refreshed slower than the janitor's idle reap interval; operator copies 8-char sig after the pool already recycled it; scripts racing each other to kill the same leaked browser.","solutions":["Re-fetch GET /monitor/browsers and use a currently listed signature (first 8 chars).","Treat 404 as success in idempotent cleanup scripts - the goal (browser gone) is already achieved.","Longer prefixes are fine and safer: send all 8 characters rather than 2-3 ambiguous ones."],"exampleFix":"# before\nresp = post(f\"{base}/monitor/actions/kill_browser\", json={\"sig\": sig})\nresp.raise_for_status()  # 404 on already-reaped browser\n\n# after\nresp = post(f\"{base}/monitor/actions/kill_browser\", json={\"sig\": sig})\nif resp.status_code == 404:\n    logger.info(f\"browser {sig} already gone\")  # idempotent success\nelse:\n    resp.raise_for_status()","handlingStrategy":"fallback","validationCode":"def browser_exists(base, sig: str) -> bool:\n    data = get(f\"{base}/monitor/browsers\").json()\n    return any(\n        b.get('sig', '').startswith(sig)\n        for b in data.get('browsers', [])\n    )","typeGuard":null,"tryCatchPattern":"try:\n    resp = post(f\"{base}/monitor/actions/kill_browser\", json={'sig': sig})\n    resp.raise_for_status()\nexcept HTTPError as e:\n    if e.response.status_code == 404:\n        pass  # already gone - idempotent success\n    else:\n        raise","preventionTips":["Always re-fetch the browser list immediately before killing; sigs go stale between janitor sweeps.","Send the full 8-char prefix to avoid ambiguous or stale short prefixes.","Treat 404 as success in cleanup automation."],"tags":["fastapi","browser-pool","not-found","admin-actions"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}