MiniMax-AI/skills · error · SystemExit
No task_id in response: {json.dumps(data, indent=2)}
Error message
No task_id in response: {json.dumps(data, indent=2)} What it means
After create_task() gets HTTP 200 and base_resp OK, it expects a task_id in the JSON. If absent, the response shape is unexpected — an API revision change, a proxy/gateway wrapper, or an error returned without a base_resp block. The full JSON is dumped to aid diagnosis.
Source
Thrown at skills/gif-sticker-maker/scripts/minimax_video.py:110
"prompt_optimizer": prompt_optimizer,
}
if first_frame_image:
payload["first_frame_image"] = first_frame_image
resp = requests.post(
f"{API_BASE}/video_generation",
headers=_headers(),
json=payload,
timeout=30,
)
resp.raise_for_status()
data = resp.json()
_check_resp(data)
task_id = data.get("task_id")
if not task_id:
raise SystemExit(f"No task_id in response: {json.dumps(data, indent=2)}")
return task_id
def poll_task(task_id: str, interval: int = 10, max_wait: int = 600) -> str:
"""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", "")View on GitHub (pinned to 60aaae52bb)
Solutions
- Inspect the dumped JSON keys — they reveal whether the endpoint/contract changed.
- Confirm API_BASE ends in /v1 and points to the correct region for the key.
- Retry once; transient gateway wrappers sometimes intercept individual calls.
Example fix
# before
task_id = create_task(prompt=p, model=m)
# after - guard the contract before trusting the value
data = resp.json()
task_id = data.get('task_id')
if not task_id:
# log full body, fall back to alternate key if API changed
task_id = data.get('id') or data.get('task', {}).get('id')
if not task_id:
raise RuntimeError(f'unexpected response: {data}') Defensive patterns
Strategy: try-catch
Validate before calling
def has_task_id(resp_json: dict) -> bool:
return bool(resp_json.get('task_id'))
# after the POST, before relying on it:
if not has_task_id(data):
raise RuntimeError(f'no task_id: {data}') Type guard
def is_task_response(d) -> bool:
return isinstance(d, dict) and isinstance(d.get('task_id'), str) and bool(d['task_id']) Try / catch
try:
task_id = create_task(prompt=p, model=m)
except SystemExit as e:
raise RuntimeError(f'create_task returned no task_id: {e}') from e Prevention
- Pin API_BASE to a specific /v1 endpoint matching the script's contract.
- Log the full response body once when integrating, to lock the expected schema.
- Watch for proxy/gateway body rewriting in corporate networks.
When it happens
Trigger: POST video_generation returns 200 with valid base_resp but no task_id key — e.g. API_BASE points to the wrong version path, a proxy wraps/renames the response, or a new API revision changed the contract.
Common situations: API_BASE missing the /v1 suffix or pointing to the wrong region; corporate proxy rewrites the body; SDK called against a newer/older API version than the script targets.
Related errors
- No download_url 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/05d4772d3f5363a5.
Report an issue: GitHub.