{"record":{"id":"12f403392e5f243e","repo":"mvanhorn/last30days-skill","slug":"gemini-request-failed-exc","errorCode":null,"errorMessage":"Gemini request failed: {exc}","messagePattern":"Gemini request failed: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/last30days/scripts/evaluate_search_quality.py","lineNumber":233,"sourceCode":"def call_gemini_judge(api_key: str, model: str, prompt: str) -> dict[str, Any]:\n    body = {\n        \"contents\": [{\"parts\": [{\"text\": prompt}]}],\n        \"generationConfig\": {\"temperature\": 0, \"responseMimeType\": \"application/json\"},\n    }\n    request = Request(\n        GEMINI_API_URL.format(model=model, api_key=api_key),\n        data=json.dumps(body).encode(\"utf-8\"),\n        headers={\"Content-Type\": \"application/json\"},\n        method=\"POST\",\n    )\n    try:\n        with urlopen(request, timeout=120) as response:\n            payload = json.loads(response.read().decode(\"utf-8\"))\n    except HTTPError as exc:\n        detail = exc.read().decode(\"utf-8\", errors=\"replace\")\n        raise RuntimeError(f\"Gemini HTTP {exc.code}: {detail}\") from exc\n    except URLError as exc:\n        raise RuntimeError(f\"Gemini request failed: {exc}\") from exc\n    return json.loads(extract_gemini_text(payload))\n\n\ndef build_judge_prompt(topic: str, query_type: str, items: list[dict[str, Any]]) -> str:\n    item_lines = []\n    for item in items:\n        item_lines.append(\n            \"\\n\".join([\n                f\"- id: {item['key']}\",\n                f\"  source: {item['source']}\",\n                f\"  title: {item['text'][:220]}\",\n                f\"  url: {item['url']}\",\n                f\"  date: {item.get('date') or 'unknown'}\",\n            ])\n        )\n    return f\"\"\"\nJudge search-result relevance for a last-30-days research tool.\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/mvanhorn/last30days-skill/blob/c7460f6114449ddfe6ea3fc2f23c3d910c0e740c/skills/last30days/scripts/evaluate_search_quality.py#L215-L251","documentation":"The URLError branch of call_gemini_judge(): the request never got an HTTP response — DNS failure, connection refused, TLS error, or the 120-second timeout expiring (socket.timeout is wrapped in URLError). RuntimeError preserves the original exception as __cause__.","triggerScenarios":"urlopen(request, timeout=120) raising URLError: no route to generativelanguage.googleapis.com (offline sandbox/CI), proxy or corporate firewall blocking the host, DNS resolution failure, or generation exceeding the 120s timeout (socket timeout surfaces as URLError reason).","commonSituations":"CI runners without network egress; local proxy env vars (HTTP_PROXY/HTTPS_PROXY) pointing at a dead proxy; IPv6-only misrouting; very large judge prompts making the model exceed 120s.","solutions":["Check basic connectivity: curl -sS https://generativelanguage.googleapis.com from the same environment.","Unset or fix HTTP_PROXY/HTTPS_PROXY/ALL_PROXY if a stale proxy is configured.","If timeouts (reason contains 'timed out'), reduce the number of items passed to build_judge_prompt or raise the timeout in urlopen.","Retry with backoff for transient DNS/socket errors before giving up."],"exampleFix":"# before\nwith urlopen(request, timeout=120) as response:\n\n# after\nwith urlopen(request, timeout=300) as response:","handlingStrategy":"retry","validationCode":"import socket\nsocket.create_connection(('generativelanguage.googleapis.com', 443), timeout=10)  # preflight","typeGuard":null,"tryCatchPattern":"try:\n    return call_gemini_judge(api_key, model, prompt)\nexcept RuntimeError as exc:\n    if 'request failed' not in str(exc):\n        raise\n    # network-level failure: backoff once, then report connectivity problem\n    time.sleep(5)\n    return call_gemini_judge(api_key, model, prompt)","preventionTips":["Preflight connectivity in CI/sandboxed environments before launching evaluation batches.","Keep judge prompts small enough that generation finishes well under the 120s timeout.","Pin correct HTTP(S)_PROXY settings or disable stale proxies in cron environments."],"tags":["gemini","network","timeout","proxy"],"backgroundTag":null,"analyzedSha":"c7460f6114449ddfe6ea3fc2f23c3d910c0e740c","analyzedAt":"2026-08-15T03:34:49.540Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}