{"record":{"id":"fb28104941859fc6","repo":"MiniMax-AI/skills","slug":"no-download-url-in-response-json-dumps-data-ind-fb2810","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/gif-sticker-maker/scripts/minimax_video.py","lineNumber":160,"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":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/gif-sticker-maker/scripts/minimax_video.py#L142-L178","documentation":"download_video() called GET files/retrieve, got HTTP 200 + valid base_resp, but data['file']['download_url'] is missing or empty. The file_id may be invalid/expired, the file not yet ready, or the response contract changed. The full JSON is dumped for diagnosis.","triggerScenarios":"files/retrieve returns a file object without download_url — file_id stale, file retention expired, propagation delay after Success, or response contract drift.","commonSituations":"Long delay between poll success and download; file_id from an old/reused task; file expired past MiniMax retention; API contract changed the nested key path.","solutions":["Inspect the dumped JSON for the actual file object shape.","Re-retrieve shortly — download_url may need propagation time after Success.","Re-query video_generation to get a fresh file_id if the old one expired."],"exampleFix":"# before\ndownload_video(file_id, out_path)  # SystemExit: No download_url\n\n# after - tolerate propagation lag\nfor _ in range(3):\n    try:\n        download_video(file_id, out_path); break\n    except SystemExit as e:\n        if 'download_url' in str(e):\n            time.sleep(5); continue\n        raise","handlingStrategy":"validation","validationCode":"def has_download_url(resp_json: dict) -> bool:\n    return bool(resp_json.get('file', {}).get('download_url'))\n# after files/retrieve, before downloading:\nif not has_download_url(data):\n    raise RuntimeError(f'no download_url: {data}')","typeGuard":"def is_retrievable(d) -> bool:\n    f = d.get('file') if isinstance(d, dict) else None\n    return isinstance(f, dict) and isinstance(f.get('download_url'), str) and bool(f['download_url'])","tryCatchPattern":"try:\n    download_video(file_id, out_path)\nexcept SystemExit as e:\n    if 'download_url' in str(e):\n        time.sleep(5); download_video(file_id, out_path)\n    else:\n        raise","preventionTips":["Download promptly after poll success to avoid file retention expiry.","Validate the nested file.download_url path before trusting it.","If contract drifts, re-query the task for a fresh file_id."],"tags":["api","video-generation","response-shape","minimax"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}