MiniMax-AI/skills · error · SystemExit
No download_url in response: {json.dumps(data, indent=2)}
Error message
No download_url in response: {json.dumps(data, indent=2)} What it means
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.
Source
Thrown at skills/gif-sticker-maker/scripts/minimax_video.py:160
raise SystemExit(f"Timeout after {max_wait}s. task_id={task_id}, check manually.")
def download_video(file_id: str, output_path: str):
"""Retrieve download URL via file_id and save the video."""
resp = requests.get(
f"{API_BASE}/files/retrieve",
headers=_headers(),
params={"file_id": file_id},
timeout=30,
)
resp.raise_for_status()
data = resp.json()
_check_resp(data)
download_url = data.get("file", {}).get("download_url", "")
if not download_url:
raise SystemExit(f"No download_url in response: {json.dumps(data, indent=2)}")
print(f" Downloading from {download_url[:80]}...")
video_resp = requests.get(download_url, timeout=300)
video_resp.raise_for_status()
os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
with open(output_path, "wb") as f:
f.write(video_resp.content)
print(f"OK: {len(video_resp.content)} bytes -> {output_path}")
def generate(
prompt: str,
output_path: str,
model: str = "MiniMax-Hailuo-2.3",
duration: int = 6,
resolution: str = "768P",View on GitHub (pinned to 60aaae52bb)
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.
Example fix
# before
download_video(file_id, out_path) # SystemExit: No download_url
# after - tolerate propagation lag
for _ in range(3):
try:
download_video(file_id, out_path); break
except SystemExit as e:
if 'download_url' in str(e):
time.sleep(5); continue
raise Defensive patterns
Strategy: validation
Validate before calling
def has_download_url(resp_json: dict) -> bool:
return bool(resp_json.get('file', {}).get('download_url'))
# after files/retrieve, before downloading:
if not has_download_url(data):
raise RuntimeError(f'no download_url: {data}') Type guard
def is_retrievable(d) -> bool:
f = d.get('file') if isinstance(d, dict) else None
return isinstance(f, dict) and isinstance(f.get('download_url'), str) and bool(f['download_url']) Try / catch
try:
download_video(file_id, out_path)
except SystemExit as e:
if 'download_url' in str(e):
time.sleep(5); download_video(file_id, out_path)
else:
raise Prevention
- 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.
When it happens
Trigger: files/retrieve returns a file object without download_url — file_id stale, file retention expired, propagation delay after Success, or response contract drift.
Common situations: 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.
Related errors
- No task_id in response: {json.dumps(data, indent=2)}
- API Error [{code}]: {msg}
- Task succeeded but no file_id returned
- Video generation failed: {json.dumps(data, indent=2)}
- ERROR: MINIMAX_API_BASE is not set.
AI-assisted analysis of MiniMax-AI/skills@60aaae52bb (2026-08-13).
Data as JSON: /api/errors/fb28104941859fc6.
Report an issue: GitHub.