calesthio/OpenMontage · error · TimeoutError

Kling Turbo task {task_id} timed out after {timeout_seconds}

Error message

Kling Turbo task {task_id} timed out after {timeout_seconds}s

What it means

Raised as a TimeoutError when poll_turbo() exceeds timeout_seconds (default 900) without the task reaching any terminal status. The Turbo poll loop re-queries GET /tasks every poll_interval seconds and gives up cleanly at the deadline.

Source

Thrown at tools/_kling/client.py:135

        while time.time() < deadline:
            data = self.get("/tasks", params={"task_ids": task_id})
            records = data.get("data") or []
            if not records:
                raise KlingAPIError(f"Kling Turbo poll response missing data[0]: {data}")
            record = records[0]
            status = record.get("status") or record.get("task_status")
            if status == TURBO_SUCCESS_STATUS:
                outputs = record.get("outputs") or []
                if not isinstance(outputs, list):
                    raise KlingAPIError("Kling Turbo result path data[0].outputs is not a list")
                return outputs
            if status == TURBO_FAILURE_STATUS:
                message = record.get("message") or record.get("error") or "Kling Turbo task failed"
                raise KlingAPIError(str(message), code=record.get("code"), request_id=record.get("request_id"), response=data)
            if status not in TURBO_PENDING_STATUSES:
                raise KlingAPIError(f"Unexpected Kling Turbo task status {status!r}", response=data)
            time.sleep(min(poll_interval, max(0.0, deadline - time.time())))
        raise TimeoutError(f"Kling Turbo task {task_id} timed out after {timeout_seconds}s")

    def _request(self, method: str, path: str, **kwargs: Any) -> dict[str, Any]:
        url = self._url(path)
        last_error: KlingAPIError | None = None
        for attempt in range(self.max_retries + 1):
            try:
                response = getattr(self.session, method)(url, headers=self.headers, timeout=30, **kwargs)
                self._raise_for_http_error(response)
                data = response.json()
                self._raise_for_business_error(data)
                return data
            except KlingAPIError as error:
                last_error = error
                if attempt >= self.max_retries or not is_retryable_kling_error(error):
                    raise
                time.sleep(min(2.0 * (attempt + 1), 8.0))
            except requests.RequestException as exc:
                last_error = KlingAPIError(str(exc))

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Raise timeout_seconds (e.g. 1800) for long or premium generations
  2. Query the task once more manually after the timeout to see if it later completed — download results rather than resubmitting (avoids duplicate cost)
  3. Increase poll_interval slightly to reduce request volume during known backlogs
  4. Build resume-by-task_id logic so a timeout does not force a fresh generation

Example fix

// before
outputs = client.poll_turbo(task_id, timeout_seconds=300)

// after
outputs = client.poll_turbo(task_id, timeout_seconds=1800, poll_interval=10.0)
Defensive patterns

Strategy: retry

Try / catch

try:
    outputs = client.poll_turbo(task_id, timeout_seconds=900)
except TimeoutError:
    outputs = client.poll_turbo(task_id, timeout_seconds=1800, poll_interval=15.0)  # resume same task

Prevention

When it happens

Trigger: Turbo generation legitimately taking longer than the configured budget (long multi-second 2K clips); gateway queue backlog; task stuck in pending due to upstream congestion; timeout_seconds lowered by the caller below realistic completion time.

Common situations: High-load periods on the Turbo service; default 900s insufficient for premium long generations; polling a task that will never complete because it failed in a way that leaves status pending.

Understand the failure class

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/cdae9b15b349aa6a. Report an issue: GitHub.