calesthio/OpenMontage · error · KlingAPIError
Kling TTS result path data.task_result.audios is not a list
Error message
Kling TTS result path data.task_result.audios is not a list
What it means
Raised as KlingAPIError when the create response contains data.task_result.audios but it is not a JSON list. This is a defensive shape check: the code found the key but cannot iterate it (e.g. it arrived as a dict keyed by index, or a string).
Source
Thrown at tools/audio/kling_tts.py:251
) -> tuple[str, list[dict[str, Any]]]:
"""Create a TTS task and return audio outputs.
Official TTS may return a completed task and task_result.audios[]
directly from POST /v1/audio/tts. Older/async behavior still requires
polling GET /v1/audio/tts/{task_id}, so support both shapes.
"""
if hasattr(client, "post"):
data = client.post(request["path"], request["payload"])
payload = data.get("data") or {}
task_id = payload.get("task_id")
if not task_id:
raise KlingAPIError(f"Kling TTS create response missing data.task_id: {data}")
task_result = payload.get("task_result") or {}
outputs = task_result.get("audios")
if outputs is not None:
if not isinstance(outputs, list):
raise KlingAPIError("Kling TTS result path data.task_result.audios is not a list")
return str(task_id), outputs
status = payload.get("task_status") or payload.get("status")
if status == "failed":
message = payload.get("task_status_msg") or payload.get("message") or "Kling TTS task failed"
raise KlingAPIError(str(message), code=payload.get("task_status"), response=data)
return str(task_id), client.poll_classic(
request["path"],
str(task_id),
"audios",
timeout_seconds=int(inputs.get("timeout_seconds", 300)),
poll_interval=float(inputs.get("poll_interval", 3.0)),
)
task_id = client.create_classic_task(request["path"], request["payload"])
return task_id, client.poll_classic(
request["path"],View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Log the offending task_result to see the actual type
- If the upstream shape legitimately changed, adapt: wrap dict values or json.loads strings before the check
- For tests, fix the fixture to use a list of url-bearing objects
Defensive patterns
Strategy: type-guard
Type guard
def is_audio_list(outputs: Any) -> bool:
return isinstance(outputs, list) Try / catch
try:
result = kling_tts_tool.execute(inputs)
except KlingAPIError as e:
if "audios is not a list" in str(e):
# envelope drift: log and fall back to polling path
logger.warning("kling audios shape changed: %s", e)
raise
raise Prevention
- Pin tests/fixtures to documented response schemas
- Treat shape changes as upstream API drift — check release notes
- Keep the defensive checks; adapt only after confirming the new shape
When it happens
Trigger: Kling returns audios as an object instead of an array, or as a serialized string; nonstandard response from an intermediate gateway re-encoding the payload.
Common situations: API envelope drift between classic and new protocol versions; a proxy transforming arrays; mock/stub responses in tests built with the wrong shape.
Related errors
- Kling TTS create response missing data.task_id: {data}
- Kling TTS response item contained no downloadable URL: {item
- Kling Classic create response missing data.task_id: {data}
- Kling Classic result path data.task_result.{result_key} is n
- Doubao submit succeeded but did not return data.task_id
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/4a740f3f7878b4d1.
Report an issue: GitHub.