calesthio/OpenMontage · error · AtlasError
Atlas Cloud upload returned no URL: {str(data)[:500]}
Error message
Atlas Cloud upload returned no URL: {str(data)[:500]} What it means
Raised by upload_media when the upload request and envelope parsing succeeded but the payload contains neither download_url nor url — the two documented shapes for the hosted-asset response. The server accepted the file but the response lacks any retrievable location, so the caller cannot proceed to use it as a reference URL. The truncated payload is included.
Source
Thrown at tools/atlas_client.py:216
raise AtlasError(f"Cannot upload — file not found: {path}")
try:
with path.open("rb") as handle:
response = requests.post(
UPLOAD_MEDIA_ENDPOINT,
headers=_headers(api_key, json_body=False),
files={"file": (path.name, handle)},
timeout=timeout,
)
except Exception as exc: # noqa: BLE001
raise AtlasError(f"Uploading {path.name} to Atlas Cloud failed: {exc}") from exc
_raise_for_status(response, "Atlas Cloud upload")
data = _payload_of(response)
url = data.get("download_url") or data.get("url")
if not url:
raise AtlasError(f"Atlas Cloud upload returned no URL: {str(data)[:500]}")
return str(url)
def download(url: str, output_path: str | Path, timeout: int = 300) -> Path:
"""Download a generated asset to disk and return the written path."""
import requests
try:
response = requests.get(url, timeout=timeout)
except Exception as exc: # noqa: BLE001
raise AtlasError(f"Downloading Atlas Cloud output failed: {exc}") from exc
_raise_for_status(response, "Atlas Cloud output download")
path = Path(output_path)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(response.content)
return pathView on GitHub (pinned to 95e1c3d0ab)
Solutions
- Log the included payload snippet to see which field (if any) carries the URL, then extend the data.get('download_url') or data.get('url') chain in the client
- Retry the upload once — empty data on success envelopes is often transient
- Confirm you are hitting the documented UPLOAD_MEDIA_ENDPOINT for your Atlas API version
- Report to Atlas support if code 200 with no URL persists on their current endpoint
Example fix
// before
url = data.get("download_url") or data.get("url")
// after — tolerate a third documented shape
url = (
data.get("download_url")
or data.get("url")
or data.get("file", {}).get("url")
) Defensive patterns
Strategy: validation
Type guard
def upload_payload_has_url(data: dict) -> bool:
return bool(data.get("download_url") or data.get("url")) Try / catch
try:
url = atlas_client.upload_media(path, api_key)
except AtlasError as e:
if "returned no URL" in str(e):
time.sleep(3)
url = atlas_client.upload_media(path, api_key) # empty-data envelopes are often transient
else:
raise Prevention
- Keep the client's accepted field list (download_url/url) in sync with Atlas docs
- Log the payload snippet when this fires to identify renamed fields fast
- Contract-test the upload response shape in CI with a recorded fixture
When it happens
Trigger: Atlas API drift adding a new field name for the hosted URL; the endpoint returning an acknowledgment-only envelope ({code:200, data:{}}) because the upload silently failed server-side; routing the upload to a different endpoint version that uses another schema.
Common situations: Client library out of date relative to the live Atlas API; regional endpoint variants with different response fields; server-side storage failures that still return success envelopes.
Related errors
- Atlas Cloud returned an unexpected payload: {str(body)[:500]
- Atlas Cloud returned an unexpected 'data' field: {str(data)[
- Atlas Cloud did not return a prediction id: {str(data)[:500]
- Cannot upload — file not found: {path}
- Prediction {prediction_id} reported '{last_status}' but retu
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/402d759befbe5ca0.
Report an issue: GitHub.