{"record":{"id":"1059ebb2837d274d","repo":"calesthio/OpenMontage","slug":"downloading-atlas-cloud-output-failed-exc","errorCode":null,"errorMessage":"Downloading Atlas Cloud output failed: {exc}","messagePattern":"Downloading Atlas Cloud output failed: (.+?)","errorType":"exception","errorClass":"AtlasError","httpStatus":null,"severity":"error","filePath":"tools/atlas_client.py","lineNumber":227,"sourceCode":"        raise AtlasError(f\"Uploading {path.name} to Atlas Cloud failed: {exc}\") from exc\n\n    _raise_for_status(response, \"Atlas Cloud upload\")\n    data = _payload_of(response)\n\n    url = data.get(\"download_url\") or data.get(\"url\")\n    if not url:\n        raise AtlasError(f\"Atlas Cloud upload returned no URL: {str(data)[:500]}\")\n    return str(url)\n\n\ndef download(url: str, output_path: str | Path, timeout: int = 300) -> Path:\n    \"\"\"Download a generated asset to disk and return the written path.\"\"\"\n    import requests\n\n    try:\n        response = requests.get(url, timeout=timeout)\n    except Exception as exc:  # noqa: BLE001\n        raise AtlasError(f\"Downloading Atlas Cloud output failed: {exc}\") from exc\n\n    _raise_for_status(response, \"Atlas Cloud output download\")\n\n    path = Path(output_path)\n    path.parent.mkdir(parents=True, exist_ok=True)\n    path.write_bytes(response.content)\n    return path\n\n\ndef aspect_ratio_from_size(width: int, height: int, allowed: list[str]) -> str:\n    \"\"\"Pick the closest ratio in `allowed` to width/height.\n\n    OpenMontage's canonical params are width/height, but many Atlas models only\n    accept a ratio enum. Snapping to the nearest supported ratio beats sending a\n    value the model will reject.\n    \"\"\"\n    if not allowed:\n        return \"16:9\"","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/atlas_client.py#L209-L245","documentation":"Raised by download when requests.get for a generated asset URL throws any exception — DNS failure, TLS error, connection reset, or the 300s default timeout being exceeded for very large outputs on slow links. The asset was generated successfully and the URL is known; only the final fetch failed. The path writing step is never reached.","triggerScenarios":"Downloading a multi-hundred-MB generated video over slow bandwidth exceeding 300s; the hosted URL expiring (signed URLs) between generation completion and download; CDN edge issues resetting large transfers.","commonSituations":"Long queues between generation and download letting signed URLs lapse; bandwidth-constrained CI runners; retrying an old prediction's URL after its retention window; interrupted transfers on mobile networks.","solutions":["Increase the timeout argument for large video outputs (e.g. 900-1800s)","If the URL expired (usually a 403 wrapped in this path or a reset), re-poll the prediction to obtain a fresh URL","Retry the download — CDN resets on big files are common and a retry often completes","Download promptly after generation completes rather than much later"],"exampleFix":"// before\npath = atlas_client.download(url, \"out/video.mp4\")\n\n// after\npath = atlas_client.download(url, \"out/video.mp4\", timeout=1200)","handlingStrategy":"retry","validationCode":"timeout = max(300, int(expected_mb * 6))  # scale to output size before downloading","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        path = atlas_client.download(url, out_path, timeout=timeout)\n        break\n    except AtlasError as e:\n        if \"Downloading Atlas Cloud output failed\" not in str(e) or attempt == 2:\n            raise\n        time.sleep(5 * (attempt + 1))","preventionTips":["Download outputs immediately after generation — signed URLs expire","Scale the timeout to expected output size for video assets","Retry partial failures — CDN resets on large files usually succeed on a second attempt"],"tags":["atlas-cloud","download","network","timeout","large-files"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}