ATH-MaaS/Pixelle-Video · error · RuntimeError

Seedance 任务成功但未返回视频 URL: {data}

Error message

Seedance 任务成功但未返回视频 URL: {data}

What it means

_poll_until_done raises RuntimeError when the polled task reports status 'succeeded' but neither data['content']['video_url'] nor data['video_url'] contains a URL. Success without a downloadable URL is treated as a fatal inconsistency.

Source

Thrown at pixelle_video/services/api_services/video_seedance.py:158

            raise RuntimeError(f"Seedance API 未返回任务 ID: {data}")
            
        return task_id

    def _poll_until_done(self, task_id: str, max_polls: int = 120, interval: int = 5) -> str:
        # 同步更新查询接口路径
        url = f"{self.base_url}/contents/generations/tasks/{task_id}"
        
        for i in range(max_polls):
            resp = requests.get(url, headers=self._headers(), timeout=30, proxies=self._proxies())
            resp.raise_for_status()
            data = resp.json()
            
            status = data.get("status")
            if status == "succeeded":
                # 根据实际返回体,URL 位于 content.video_url 或 video_url
                video_url = data.get("content", {}).get("video_url") or data.get("video_url")
                if not video_url:
                    raise RuntimeError(f"Seedance 任务成功但未返回视频 URL: {data}")
                return video_url
            elif status in ("failed", "expired"):
                error_msg = data.get("error", {}).get("message") or data.get("status_msg") or "未知错误"
                raise RuntimeError(f"Seedance 视频生成{status}: {error_msg}")
            
            logger.debug(f"SeedanceVideoClient: 任务进行中 {task_id}, status={status}, poll={i+1}")
            time.sleep(interval)
            
        raise TimeoutError(f"Seedance 视频生成超时 (task_id={task_id})")

    def _download_video(self, url: str, save_path: str):
        os.makedirs(os.path.dirname(save_path), exist_ok=True)
        resp = requests.get(url, stream=True, timeout=120, proxies=self._proxies())
        resp.raise_for_status()
        with open(save_path, "wb") as f:
            for chunk in resp.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)

View on GitHub (pinned to 848b054e4f)

Solutions

  1. Inspect the full data payload in the error message and locate where the video URL actually lives
  2. Add fallbacks for alternate shapes, e.g. data['content']['video_url'] list vs string, data['output']['video_url']
  3. Confirm the model name passed to generate_video returns videos (not images) for this endpoint
  4. Check for API changelog/version drift between your client and the deployed Seedance API

Example fix

// before
video_url = data.get("content", {}).get("video_url") or data.get("video_url")
// after
content = data.get("content") or {}
vu = content.get("video_url") or data.get("video_url")
if isinstance(vu, list):
    vu = vu[0].get("url") if vu else None
if isinstance(vu, dict):
    vu = vu.get("url")
Defensive patterns

Strategy: try-catch

Type guard

def extract_video_url(data: dict) -> str | None:
    vu = (data.get("content") or {}).get("video_url") or data.get("video_url")
    if isinstance(vu, list):
        vu = vu[0] if vu else None
    if isinstance(vu, dict):
        vu = vu.get("url")
    return vu if isinstance(vu, str) and vu else None

Try / catch

try:
    video = client.generate_video(prompt=p, image_path=img, save_path=out)
except RuntimeError as e:
    if "未返回视频 URL" in str(e):
        logging.error(f"Seedance success payload malformed: {e}")  # adapt client to new schema
    else:
        raise

Prevention

When it happens

Trigger: Polling GET /contents/generations/tasks/{task_id} returns status=='succeeded' with an empty or differently-shaped result payload (no video_url under content or top level).

Common situations: API response schema changed (e.g. URL moved to output.video_url or a list of results); content generation produced an empty result; response truncated or proxied; using an incompatible model whose success payload differs.

Related errors


AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30). Data as JSON: /api/errors/9b3e8d8c6a549528. Report an issue: GitHub.