abi/screenshot-to-code · error · Exception
Error taking screenshot
Error message
Error taking screenshot
What it means
Bare Exception("Error taking screenshot") raised inside capture_screenshot() when the screenshotone API returns a non-200 status or an empty body. The check `response.status_code == 200 and response.content` collapses every upstream failure mode — invalid/expired API key, quota exhaustion, blocked or unreachable target URL, upstream 5xx — into one opaque message with no status code or body attached.
Source
Thrown at backend/routes/screenshot.py:73
"format": "png",
"block_ads": "true",
"block_cookie_banners": "true",
"block_trackers": "true",
"cache": "false",
"viewport_width": "342",
"viewport_height": "684",
}
if device == "desktop":
params["viewport_width"] = "1280"
params["viewport_height"] = "832"
async with httpx.AsyncClient(timeout=60) as client:
response = await client.get(api_base_url, params=params)
if response.status_code == 200 and response.content:
return response.content
else:
raise Exception("Error taking screenshot")
class ScreenshotRequest(BaseModel):
url: str
apiKey: str
class ScreenshotResponse(BaseModel):
url: str
@router.post("/api/screenshot")
async def app_screenshot(request: ScreenshotRequest):
# Extract the URL from the request body
url = request.url
api_key = request.apiKey
try:View on GitHub (pinned to d026163f58)
Solutions
- Verify the apiKey param passed to the endpoint is a valid, active screenshotone key
- Reproduce the upstream call manually with curl/httpx using the same params and inspect response.status_code and response.text to see the real error
- If quota/billing: check the screenshotone dashboard and top up or wait for reset
- Improve the raise to include status and body (see exampleFix) so future failures are diagnosable
Example fix
# before
if response.status_code == 200 and response.content:
return response.content
else:
raise Exception("Error taking screenshot")
# after
if response.status_code == 200 and response.content:
return response.content
raise Exception(
f"Screenshot API error: status={response.status_code} body={response.text[:200]}"
) Defensive patterns
Strategy: retry
Validate before calling
def validate_screenshot_request(url: str, api_key: str) -> None:
if not api_key or not api_key.strip():
raise ValueError("apiKey is required for the screenshot service")
if not is_screenshotable_url(url):
raise ValueError(f"URL not screenshotable: {url}") Try / catch
for attempt in range(2):
try:
return await capture_screenshot(url, api_key)
except Exception as e:
if str(e) == "Error taking screenshot" and attempt == 0:
await asyncio.sleep(2); continue # transient upstream failure, one retry
raise Prevention
- Keep the screenshotone key valid and monitor quota; a bad key is the most common cause
- Log upstream status/body when this fires — the message itself carries no diagnostics
- Set an httpx timeout appropriate to slow pages (the client uses 60s)
When it happens
Trigger: GET to api_base_url (screenshotone) with params including url, apiKey, viewport dims returns 401/403 (bad key), 429 (quota), 402 (payment), or 200 with zero-length content (render failure of the target page).
Common situations: Expired screenshotone API key; free-tier quota used up; target page blocks headless crawlers or takes longer than the 60s httpx timeout handled elsewhere; api_base_url region endpoint misconfigured.
Related errors
- OpenAI API key is missing.
- Anthropic API key is missing.
- Gemini API key is missing.
- Missing GEMINI_API_KEY
- Anthropic API key not found
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/50d9642854ab7fc6.
Report an issue: GitHub.