MiniMax-AI/skills · warning · SystemExit
Timeout after {max_wait}s. task_id={task_id}, check manually
Error message
Timeout after {max_wait}s. task_id={task_id}, check manually. What it means
poll_task() looped until elapsed reached max_wait (default 600s) without the status becoming Success or Fail — the job is still Processing/queued. The task is NOT dead; it continues server-side and can be checked later with the task_id.
Source
Thrown at skills/frontend-dev/scripts/minimax_video.py:107
data = resp.json()
_check_resp(data)
status = data.get("status", "")
file_id = data.get("file_id", "")
if status == "Success":
if not file_id:
raise SystemExit("Task succeeded but no file_id returned")
print(f" Done! file_id={file_id}")
return file_id
elif status == "Fail":
raise SystemExit(f"Video generation failed: {json.dumps(data, indent=2)}")
else:
print(f" [{elapsed}s] Status: {status}...")
time.sleep(interval)
elapsed += interval
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)}")
View on GitHub (pinned to 60aaae52bb)
Solutions
- Raise the budget: re-run with `--max-wait 1200` (or pass max_wait=1200), keeping poll interval reasonable.
- Do NOT discard the task_id from the dumped message — re-query GET {API_BASE}/query/video_generation?task_id=... later to resume waiting without re-creating the task.
- Lower the work: use 768P/720P and duration 6 to finish faster within the window.
- If timeouts are routine, build a resume-capable wrapper that persists task_id and polls across runs.
Example fix
// before: fixed 600s ceiling, task lost on timeout
raise SystemExit(f"Timeout after {max_wait}s. task_id={task_id}")
// after: persist task_id and support resume, raise ceiling
import json, pathlib
pathlib.Path(".video_task").write_text(task_id)
# re-run mode: python minimax_video.py --resume <task_id>
raise TimeoutError(f"still processing; task_id={task_id} saved for resume") Defensive patterns
Strategy: retry
Validate before calling
import json, pathlib
def run_video_resumable(prompt, out, max_wait=1200, task_store=pathlib.Path(".video_task")):
"""Raise max_wait and persist task_id so a timeout can be resumed."""
task_id = task_store.read_text() if task_store.exists() else None
if not task_id:
task_id = create_task(prompt, ...)
task_store.write_text(task_id)
file_id = poll_task(task_id, interval=10, max_wait=max_wait) # may raise TimeoutError
download_video(file_id, out)
task_store.unlink(missing_ok=True) Type guard
def is_processing(status: str) -> bool:
"""True when the task is still in a non-terminal (non-Success/Fail) state."""
return status not in {"Success", "Fail"} Try / catch
import subprocess, sys
timeout = 1200
while True:
r = subprocess.run([sys.executable, "minimax_video.py", prompt, "-o", out, "--max-wait", str(timeout)], capture_output=True, text=True)
if r.returncode == 0:
break
if "Timeout after" in (r.stderr or r.stdout or ""):
tid = extract_task_id(r.stdout or r.stderr) # task_id is in the message
timeout = 600 # shorter re-poll window; same task_id continues server-side
continue
raise RuntimeError(r.stderr or r.stdout) Prevention
- Raise --max-wait (e.g. 1200) for 1080P/10s jobs that routinely exceed 600s.
- Persist the task_id from the timeout message and resume by re-querying instead of re-creating.
- Prefer 768P/720P + duration 6 to stay safely within the default window.
- Build a resume-capable wrapper so timeouts don't discard paid work.
When it happens
Trigger: Long generations (1080P, 10s duration) under load exceeding the default 600s window; high platform concurrency slowing the queue; a too-aggressive poll that exits just before completion; max_wait lowered by the caller.
Common situations: First-time 1080P/10s jobs during peak hours; account tier with lower scheduling priority; default 600s too short for the chosen quality; network hiccup making each poll slow so fewer effective checks occur.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Generation incomplete (status={status}): {json.dumps(data, i
- Task succeeded but no file_id returned
- No download_url in response: {json.dumps(data, indent=2)}
- API Error [{code}]: {msg}
- No task_id in response: {json.dumps(data, indent=2)}
AI-assisted analysis of MiniMax-AI/skills@60aaae52bb (2026-08-13).
Data as JSON: /api/errors/91b9db4cd9d1a9e0.
Report an issue: GitHub.