{"record":{"id":"99d29e10bd46c269","repo":"calesthio/OpenMontage","slug":"timeout-seconds-must-be-greater-than-0","errorCode":null,"errorMessage":"timeout_seconds must be greater than 0","messagePattern":"timeout_seconds must be greater than 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/video/seedance_ark.py","lineNumber":1319,"sourceCode":"            f\"{self._get_base_url()}/contents/generations/tasks/{task_id}\",\n            headers=self._headers(api_key),\n            timeout=30,\n        )\n        # The official DELETE success body is undefined and may be empty.\n        self._raise_for_status(response)\n\n    def _poll_task(\n        self,\n        task_id: str,\n        api_key: str,\n        inputs: dict[str, Any],\n    ) -> 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:","sourceCodeStart":1301,"sourceCodeEnd":1337,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/seedance_ark.py#L1301-L1337","documentation":"ValueError raised in _poll_task when the optional timeout_seconds input is zero or negative. This value defines the monotonic deadline for how long the tool will keep polling the Ark task before giving up; a non-positive deadline is nonsensical and is rejected before the first query. Default is 1200 seconds.","triggerScenarios":"Passing timeout_seconds=0 expecting 'no timeout' (the opposite happens), negative values, or unit confusion such as passing milliseconds (e.g. 500 meaning 500ms is fine, but 0 or -1 is not).","commonSituations":"Developers assuming 0 means infinite; config templating that substitutes an unset variable as 0; reusing a 'disabled' flag value (-1) from another system as the timeout.","solutions":["Pick a realistic positive timeout: Seedance generations typically need 60-1200 seconds depending on duration and resolution.","If you intended 'wait forever', pass a large value like 3600 instead of 0.","Omit the key to accept the 1200-second default."],"exampleFix":"# before\ninputs = {\"timeout_seconds\": 0}\n\n# after\ninputs = {\"timeout_seconds\": 1800}","handlingStrategy":"validation","validationCode":"timeout = float(inputs.get(\"timeout_seconds\", 1200))\nif timeout <= 0:\n    inputs[\"timeout_seconds\"] = 1800  # never send 0 meaning 'infinite'","typeGuard":"def is_valid_poll_timeout(v) -> bool:\n    try:\n        return float(v) > 0\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":null,"preventionTips":["Never use 0 or -1 as 'disabled' sentinels for this tool — they are rejected.","Budget timeout by expected generation time: duration x resolution, plus queue margin."],"tags":["validation","seedance","ark","timeout"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}