{"record":{"id":"f1ab98ba789c9467","repo":"MiniMax-AI/skills","slug":"no-download-url-in-response-json-dumps-data-ind","errorCode":null,"errorMessage":"No download_url in response: {json.dumps(data, indent=2)}","messagePattern":"No download_url in response: (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/frontend-dev/scripts/minimax_video.py","lineNumber":124,"sourceCode":"\n    raise SystemExit(f\"Timeout after {max_wait}s. task_id={task_id}, check manually.\")\n\n\ndef download_video(file_id: str, output_path: str):\n    \"\"\"Retrieve download URL via file_id and save the video.\"\"\"\n    resp = requests.get(\n        f\"{API_BASE}/files/retrieve\",\n        headers=_headers(),\n        params={\"file_id\": file_id},\n        timeout=30,\n    )\n    resp.raise_for_status()\n    data = resp.json()\n    _check_resp(data)\n\n    download_url = data.get(\"file\", {}).get(\"download_url\", \"\")\n    if not download_url:\n        raise SystemExit(f\"No download_url in response: {json.dumps(data, indent=2)}\")\n\n    print(f\"  Downloading from {download_url[:80]}...\")\n    video_resp = requests.get(download_url, timeout=300)\n    video_resp.raise_for_status()\n\n    os.makedirs(os.path.dirname(output_path) or \".\", exist_ok=True)\n    with open(output_path, \"wb\") as f:\n        f.write(video_resp.content)\n\n    print(f\"OK: {len(video_resp.content)} bytes -> {output_path}\")\n\n\ndef generate(\n    prompt: str,\n    output_path: str,\n    model: str = \"MiniMax-Hailuo-2.3\",\n    duration: int = 6,\n    resolution: str = \"768P\",","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/frontend-dev/scripts/minimax_video.py#L106-L142","documentation":"download_video() called GET {API_BASE}/files/retrieve with a file_id; HTTP 2xx and base_resp OK, but data.file.download_url is empty/missing. Without the URL the video cannot be fetched, and the full JSON is dumped.","triggerScenarios":"The file is not yet ready for retrieval (file_id exists but the downloadable artifact isn't attached yet); the file_id expired or was already consumed; a schema that nests download_url differently; transient backend issue producing an empty URL.","commonSituations":"Calling files/retrieve immediately after Success where file_id is set but the asset isn't linkable yet; region/endpoint returning the URL under a sibling key; expired link after a long delay between poll and download.","solutions":["Retry files/retrieve after a short delay — the download URL often appears shortly after Success.","Inspect the dumped JSON to find the correct key (e.g. data.download_url, data.file.url).","Re-poll the task to confirm the file_id is still valid and re-retrieve.","If it persists, fetch manually via the dashboard using the file_id."],"exampleFix":"// before: single expected nested key\ndownload_url = data.get(\"file\", {}).get(\"download_url\", \"\")\n\n// after: try alternates and retry once\nfor _ in range(3):\n    download_url = (data.get(\"file\", {}).get(\"download_url\")\n                    or data.get(\"download_url\")\n                    or data.get(\"file\", {}).get(\"url\", \"\"))\n    if download_url:\n        break\n    time.sleep(5); data = retrieve(file_id)\nif not download_url:\n    raise RuntimeError(\"no download_url after retries\")","handlingStrategy":"retry","validationCode":"def read_download_url(data: dict):\n    \"\"\"Return download URL from plausible locations, else None.\"\"\"\n    for path in ((\"file\", \"download_url\"), (\"download_url\",), (\"file\", \"url\")):\n        v = data\n        for k in path:\n            v = v.get(k, {}) if isinstance(v, dict) else None\n        if v:\n            return v\n    return None","typeGuard":"def has_download_url(data: dict) -> bool:\n    \"\"\"True when the files/retrieve response carries a downloadable URL.\"\"\"\n    return bool(read_download_url(data))","tryCatchPattern":"for attempt in range(3):\n    data = retrieve(file_id)\n    if data.get(\"base_resp\", {}).get(\"status_code\", 0) == 0:\n        url = read_download_url(data)\n        if url:\n            return url\n    time.sleep(5)\nraise RuntimeError(\"no download_url after retries\")","preventionTips":["Retry files/retrieve shortly after Success — the URL often lags the file_id.","Tolerate alternate key locations (download_url, file.url) when reading the response.","Don't wait too long between poll-success and retrieve, since links can expire.","If it persists, retrieve manually via the dashboard using the file_id."],"tags":["api","data-integrity","transient","minimax","video"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}