NanmiCoder/MediaCrawler · error · HTTPException
Not a file
Error message
Not a file
What it means
A precondition check in _create_browser_context: it refuses to build a Playwright BrowserContext when self.browser is None, i.e. _connect_via_cdp never ran or failed before a context was requested. It is a guard exception, not an external failure — the caller tried to use the manager before a successful CDP connection was established.
Source
Thrown at api/routers/data.py:107
except Exception:
continue
# Sort by modification time (newest first)
files.sort(key=lambda x: x["modified_at"], reverse=True)
return {"files": files}
@router.get("/files/{file_path:path}")
async def get_file_content(file_path: str, preview: bool = True, limit: int = 100):
"""Get file content or preview"""
full_path = DATA_DIR / file_path
if not full_path.exists():
raise HTTPException(status_code=404, detail="File not found")
if not full_path.is_file():
raise HTTPException(status_code=400, detail="Not a file")
# Security check: ensure within DATA_DIR
try:
full_path.resolve().relative_to(DATA_DIR.resolve())
except ValueError:
raise HTTPException(status_code=403, detail="Access denied")
if preview:
# Return preview data
try:
if full_path.suffix == ".json":
with open(full_path, "r", encoding="utf-8") as f:
data = json.load(f)
if isinstance(data, list):
return {"data": data[:limit], "total": len(data)}
return {"data": data, "total": 1}
elif full_path.suffix == ".csv":
import csvView on GitHub (pinned to d6f7c5bb90)
Solutions
- Ensure the connect step runs to completion before any context/page request — call _connect_via_cdp and only proceed on success
- Check the manager state before use: `if not cdp_manager.browser: await cdp_manager.connect(...)`
- If the connection may drop mid-session, wrap connect+context creation so a failed connect retries from launching the browser, not just context creation
- Hunt upstream for swallowed exceptions that let execution reach this guard with browser=None
Example fix
// before
browser_context = await self._create_browser_context(proxy, user_agent)
// after
if not self.browser:
raise RuntimeError("Browser not connected")
browser_context = await self._create_browser_context(proxy, user_agent) Defensive patterns
Strategy: validation
Validate before calling
async def ensure_connected(manager, playwright) -> None:
if not getattr(manager, "browser", None) or not manager.browser.is_connected():
await manager._connect_via_cdp(playwright)
assert manager.browser and manager.browser.is_connected(), "connect step did not yield a live browser"
# call ensure_connected(manager, playwright) BEFORE _create_browser_context Type guard
def manager_ready(manager) -> bool:
browser = getattr(manager, "browser", None)
return browser is not None and browser.is_connected() Try / catch
try:
ctx = await manager._create_browser_context(proxy, ua)
except RuntimeError as e:
if "Browser not connected" in str(e):
await manager.start() # full reconnect, then retry once
ctx = await manager._create_browser_context(proxy, ua)
else:
raise Prevention
- Treat this guard as a bug in the caller: fix the call ordering, do not catch it routinely
- Never swallow exceptions from the connect step — they turn into this precondition error later
- Reset the manager to a known state (browser=None) only together with full teardown so state cannot drift
When it happens
Trigger: Calling _create_browser_context before _connect_via_cdp succeeds; after a previous connection dropped and self.browser was reset to None; an earlier connect_over_cdp exception was swallowed upstream so the manager is in an uninitialized state.
Common situations: Startup race: the crawler requests a page while Chrome/DevTools is still booting; a prior run's cleanup set browser=None and code reused the manager instance; exception handlers that log-and-continue past a failed connect then proceed to context creation.
Related errors
- Crawler is already running
- File not found
- Cannot find available port, tried {start_port} to {port-1}
- Cannot connect to existing browser on port {self.debug_port}
- Browser failed to start within {config.BROWSER_LAUNCH_TIMEOU
AI-assisted analysis of NanmiCoder/MediaCrawler@d6f7c5bb90 (2026-08-15).
Data as JSON: /api/errors/456b0d10eb84c128.
Report an issue: GitHub.