{"record":{"id":"bb9a78276f96dc2f","repo":"jamiepine/voicebox","slug":"label-failed-to-fetch-checksum-from-sha256-url","errorCode":null,"errorMessage":"{label}: failed to fetch checksum from {sha256_url}","messagePattern":"(.+?): failed to fetch checksum from (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"backend/services/cuda.py","lineNumber":199,"sourceCode":"        total_size: Total bytes across all downloads (for progress bar)\n    \"\"\"\n    progress = get_progress_manager()\n    temp_path = dest_dir / f\".download-{label.replace(' ', '-')}.tmp\"\n\n    # Clean up leftover partial download\n    if temp_path.exists():\n        temp_path.unlink()\n\n    # Fetch expected checksum (fail-fast: never extract an unverified archive)\n    expected_sha = None\n    if sha256_url:\n        try:\n            sha_resp = await client.get(sha256_url)\n            sha_resp.raise_for_status()\n            expected_sha = sha_resp.text.strip().split()[0]\n            logger.info(f\"{label}: expected SHA-256: {expected_sha[:16]}...\")\n        except Exception as e:\n            raise RuntimeError(f\"{label}: failed to fetch checksum from {sha256_url}\") from e\n\n    # Stream download, verify, and extract — always clean up temp file\n    downloaded = 0\n    try:\n        async with client.stream(\"GET\", url) as response:\n            response.raise_for_status()\n            with open(temp_path, \"wb\") as f:\n                async for chunk in response.aiter_bytes(chunk_size=1024 * 1024):\n                    f.write(chunk)\n                    downloaded += len(chunk)\n                    progress.update_progress(\n                        PROGRESS_KEY,\n                        current=progress_offset + downloaded,\n                        total=total_size,\n                        filename=f\"Downloading {label}\",\n                        status=\"downloading\",\n                    )\n","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/cuda.py#L181-L217","documentation":"_download_and_extract_archive() fetches the .sha256 sidecar from the GitHub release URL before downloading the archive, so it never extracts an unverified file. If client.get(sha256_url) raises (raise_for_status() on non-2xx, timeout, DNS, or any other exception) the except block re-raises as RuntimeError chained from the original. The client is created with timeout=30.0 in download_cuda_binary().","triggerScenarios":"The .sha256 asset wasn't uploaded for the target release tag (404), transient network outage or DNS failure reaching github.com, GitHub rate-limiting, a proxy/firewall blocking the release-download domain, or the 30s httpx timeout elapsings on a slow link.","commonSituations":"A release tag missing the .sha256 sidecar artifact; corporate proxy blocking github.com; first CUDA backend download on a constrained Windows machine; typo'd/custom version argument pointing at a non-existent release.","solutions":["Verify the release page for the version tag actually has the .sha256 asset uploaded.","Retry — transient GitHub/network errors frequently clear on the next attempt.","Confirm github.com is reachable (no proxy/firewall block) from the host.","Ensure the version passed to download_cuda_binary matches an existing published release tag."],"exampleFix":"# before\nsha_resp = await client.get(sha256_url)\nsha_resp.raise_for_status()\n\n# after — surface HTTP status for diagnosis\nsha_resp = await client.get(sha256_url)\nif sha_resp.status_code != 200:\n    raise RuntimeError(f\"{label}: checksum HTTP {sha_resp.status_code} at {sha256_url}\")\nsha_resp.raise_for_status()","handlingStrategy":"retry","validationCode":"import httpx\n\nasync def checksum_reachable(base_url: str, archive: str) -> bool:\n    async with httpx.AsyncClient(timeout=10.0) as c:\n        r = await c.head(f\"{base_url}/{archive}.sha256\")\n        return r.status_code == 200","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        await download_cuda_binary(version)\n        break\n    except RuntimeError as e:\n        if \"failed to fetch checksum\" in str(e) and attempt < 2:\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Confirm the .sha256 sidecar exists for the target release tag before triggering download.","Run downloads from a network with unrestricted github.com access.","Treat checksum-fetch failures as retriable but never skip verification."],"tags":["network","cuda","checksum","download","github-releases"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}