{"record":{"id":"e622480259e957a3","repo":"calesthio/OpenMontage","slug":"ark-task-task-id-did-not-finish-within-timeout","errorCode":null,"errorMessage":"Ark task {task_id} did not finish within {timeout}s","messagePattern":"Ark task (.+?) did not finish within (.+?)s","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"tools/video/seedance_ark.py","lineNumber":1331,"sourceCode":"    ) -> dict[str, Any]:\n        interval = float(inputs.get(\"poll_interval_seconds\", 3))\n        timeout = float(inputs.get(\"timeout_seconds\", 1200))\n        if not 0 <= interval <= 60:\n            raise ValueError(\"poll_interval_seconds must be between 0 and 60\")\n        if timeout <= 0:\n            raise ValueError(\"timeout_seconds must be greater than 0\")\n        deadline = time.monotonic() + timeout\n        while True:\n            task = self._query_task(task_id, api_key)\n            status = str(task.get(\"status\", \"\")).lower()\n            if status in self.TERMINAL_STATUSES:\n                return task\n            if status not in {\"queued\", \"running\"}:\n                raise RuntimeError(\n                    f\"Ark returned unknown task status: {status or '<empty>'}\"\n                )\n            if time.monotonic() >= deadline:\n                raise TimeoutError(\n                    f\"Ark task {task_id} did not finish within {timeout}s\"\n                )\n            time.sleep(interval)\n\n    @staticmethod\n    def _download_video(video_url: str, output_path: Path) -> None:\n        import requests\n\n        response = requests.get(video_url, timeout=120)\n        response.raise_for_status()\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        partial = output_path.with_name(output_path.name + \".part\")\n        partial.write_bytes(response.content)\n        partial.replace(output_path)\n\n    @staticmethod\n    def _validate_task_id(task_id: Any) -> None:\n        value = str(task_id or \"\")","sourceCodeStart":1313,"sourceCodeEnd":1349,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/seedance_ark.py#L1313-L1349","documentation":"TimeoutError raised in _poll_task when time.monotonic() passes the deadline (timeout_seconds, default 1200) while the task is still queued or running. The generation may still complete server-side, but this client stops waiting. The task itself is not cancelled by this raise, so it can consume credits.","triggerScenarios":"Long generations (high resolution, multi-second videos, heavy reference sets) exceeding the deadline; congested Ark queues during peak hours; or an undersized timeout_seconds paired with a slow model.","commonSituations":"First runs on sora-2-pro-class or long-duration models where 20 minutes is not enough; batch jobs where queue time stacks behind many submitted tasks.","solutions":["Increase timeout_seconds (e.g. 1800-3600) for long or high-resolution jobs.","Catch TimeoutError and recover the finished result later by querying the task_id directly instead of resubmitting (validate with the same TASK_ID_PATTERN).","Submit fewer concurrent tasks so queue wait shrinks.","If you must abandon, cancel via the task DELETE endpoint to avoid paying for an orphaned generation."],"exampleFix":"# before\ninputs = {\"timeout_seconds\": 300}  # 5 min, too short for 1080p\n\n# after\ninputs = {\"timeout_seconds\": 2400}  # 40 min budget","handlingStrategy":"try-catch","validationCode":"inputs[\"timeout_seconds\"] = max(1800, float(inputs.get(\"timeout_seconds\", 1200)))  # headroom for long jobs","typeGuard":null,"tryCatchPattern":"try:\n    result = tool.run(inputs)\nexcept TimeoutError:\n    task = tool._query_task(task_id, api_key)  # task may still complete server-side\n    if str(task.get(\"status\", \"\")).lower() in tool.TERMINAL_STATUSES:\n        return task\n    raise","preventionTips":["Size timeout_seconds to the model's worst-case generation plus queue time.","Persist task_id at submission so a timeout never means losing the generation.","Cancel orphaned tasks via the DELETE endpoint if you will not recover them."],"tags":["timeout","seedance","ark","polling"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}