calesthio/OpenMontage · error · KlingAPIError
Unexpected Kling Classic task status {status!r}
Error message
Unexpected Kling Classic task status {status!r} What it means
Raised when poll_classic() receives a task_status value that matches neither the success, failure, nor known pending statuses (CLASSIC_PENDING_STATUSES). It is a defensive guard against Kling introducing new status enum values or returning an unexpected shape, and includes the full response payload so the unknown status can be inspected.
Source
Thrown at tools/_kling/client.py:99
timeout_seconds: int = 900,
poll_interval: float = 5.0,
) -> list[dict[str, Any]]:
deadline = time.time() + timeout_seconds
while time.time() < deadline:
data = self.get(f"{path.rstrip('/')}/{task_id}")
payload = data.get("data") or {}
status = payload.get("task_status") or payload.get("status")
if status == CLASSIC_SUCCESS_STATUS:
task_result = payload.get("task_result") or {}
outputs = task_result.get(result_key) or []
if not isinstance(outputs, list):
raise KlingAPIError(f"Kling Classic result path data.task_result.{result_key} is not a list")
return outputs
if status == CLASSIC_FAILURE_STATUS:
message = payload.get("task_status_msg") or payload.get("message") or "Kling Classic task failed"
raise KlingAPIError(str(message), code=payload.get("task_status"), response=data)
if status not in CLASSIC_PENDING_STATUSES:
raise KlingAPIError(f"Unexpected Kling Classic task status {status!r}", response=data)
time.sleep(min(poll_interval, max(0.0, deadline - time.time())))
raise TimeoutError(f"Kling Classic task {task_id} timed out after {timeout_seconds}s")
def create_turbo(self, path: str, payload: dict[str, Any]) -> str:
data = self.post(path, payload)
task_id = ((data.get("data") or {}).get("id"))
if not task_id:
raise KlingAPIError(f"Kling Turbo create response missing data.id: {data}")
return str(task_id)
def poll_turbo(
self,
task_id: str,
timeout_seconds: int = 900,
poll_interval: float = 5.0,
) -> list[dict[str, Any]]:
deadline = time.time() + timeout_seconds
while time.time() < deadline:View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Log the full response (attached as error.response) to see the exact status string
- Check current Kling official API docs for the complete task_status enum
- If the status is a new pending-like state, add it to CLASSIC_PENDING_STATUSES in tools/_kling/schemas.py
- If it is a terminal state (cancelled/expired), add explicit handling for it instead of treating it as pending
Example fix
// schemas.py — before
CLASSIC_PENDING_STATUSES = {'submitted', 'processing'}
// schemas.py — after (after confirming against Kling docs)
CLASSIC_PENDING_STATUSES = {'submitted', 'processing', 'queuing'} Defensive patterns
Strategy: try-catch
Validate before calling
KNOWN = {'succeed', 'failed', 'submitted', 'processing'} # mirror schemas.py
def status_is_known(status: str) -> bool:
return status in KNOWN Type guard
from tools._kling.schemas import CLASSIC_PENDING_STATUSES, CLASSIC_SUCCESS_STATUS, CLASSIC_FAILURE_STATUS
def classify_classic_status(payload: dict) -> str:
s = (payload.get('data') or {}).get('task_status') or (payload.get('data') or {}).get('status')
if s == CLASSIC_SUCCESS_STATUS: return 'success'
if s == CLASSIC_FAILURE_STATUS: return 'failure'
if s in CLASSIC_PENDING_STATUSES: return 'pending'
return 'unknown' Try / catch
try:
outputs = client.poll_classic(path, task_id, 'videos')
except KlingAPIError as e:
if 'Unexpected Kling Classic task status' in str(e):
logger.error('unknown status — full response: %s', e.response)
# decide: extend schemas.py or treat as failure
raise Prevention
- Pin/assert the API version you develop against
- Monitor Kling release notes for new task_status enum values
- Always log the attached response payload on unknown-status errors
When it happens
Trigger: Kling adds a new intermediate status (e.g. 'staging', 'queuing') not in CLASSIC_PENDING_STATUSES in schemas.py; the API returns an unusual status string for a task in an edge state (e.g. cancelled/expired tasks); payload.get('task_status') is empty and payload.get('status') carries an unexpected value.
Common situations: Kling API version drift after an upstream release; tasks that were cancelled manually in the Kling console and now report a cancel status; regional endpoints that emit slightly different status enums.
Related errors
- Unexpected Kling Turbo task status {status!r}
- Kling Classic task failed
- Kling Classic task {task_id} timed out after {timeout_second
- Kling Turbo poll response missing data[0]: {data}
- Kling Turbo result path data[0].outputs is not a list
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/ff0c2594396f5862.
Report an issue: GitHub.