MiniMax-AI/skills · error · SystemExit

Task succeeded but no file_id returned

Error message

Task succeeded but no file_id returned

What it means

poll_task() observed status == 'Success' but file_id is empty. The server marked the task done yet omitted the result reference — an inconsistent state that should not occur normally, often a propagation race.

Source

Thrown at skills/gif-sticker-maker/scripts/minimax_video.py:133

    """Poll task status until Success. Returns file_id."""
    elapsed = 0
    while elapsed < max_wait:
        resp = requests.get(
            f"{API_BASE}/query/video_generation",
            headers=_headers(),
            params={"task_id": task_id},
            timeout=30,
        )
        resp.raise_for_status()
        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},

View on GitHub (pinned to 60aaae52bb)

Solutions

  1. Re-poll once or twice after a short delay — file_id often populates within seconds of Success.
  2. Use the task_id to query the MiniMax console manually.
  3. Report to MiniMax support if the state persists across many polls.

Example fix

# before
file_id = poll_task(task_id)

# after - tolerate a brief propagation lag
for attempt in range(3):
    file_id = poll_task(task_id)
    if file_id:
        break
    time.sleep(5)
Defensive patterns

Strategy: retry

Validate before calling

# before accepting Success, confirm file_id is present
status = data.get('status')
file_id = data.get('file_id')
if status == 'Success' and not file_id:
    # re-query after a short wait rather than aborting
    time.sleep(5); continue

Type guard

def success_with_file(d) -> bool:
    return d.get('status') == 'Success' and isinstance(d.get('file_id'), str) and bool(d['file_id'])

Try / catch

for _ in range(3):
    try:
        file_id = poll_task(task_id)
        break
    except SystemExit as e:
        if 'no file_id' in str(e):
            time.sleep(5); continue
        raise

Prevention

When it happens

Trigger: GET query/video_generation returns status 'Success' with empty or missing file_id. Most likely a race where Success is posted before the file_id is indexed server-side.

Common situations: Polling immediately after a Success transition; high server load delaying file metadata; transient API inconsistency.

Related errors


AI-assisted analysis of MiniMax-AI/skills@60aaae52bb (2026-08-13). Data as JSON: /api/errors/c7c3f763d6a69f0e. Report an issue: GitHub.