Skip to content

fix(amux): detect nested data.status in async video poll#14

Merged
duanbing merged 1 commit into
mainfrom
fix/amux-poll-status-nesting
Jun 24, 2026
Merged

fix(amux): detect nested data.status in async video poll#14
duanbing merged 1 commit into
mainfrom
fix/amux-poll-status-nesting

Conversation

@duanbing

Copy link
Copy Markdown

Problem

Every Doubao-Seedance video generation polled amux for the full ASYNC_TASK_TIMEOUT (3600s) and then failed with did not complete within 3600s — even though the render succeeded on amux's side (and was billed upstream, ~87k tokens per discarded task).

Root cause

The universal poll endpoint GET /v1/video/generations/{task_id} returns:

{"code":"success","data":{"status":"succeeded","url":"https://cdn.amux.ai/…mp4"}}

But poll_async_result read the root-level status and only matched "completed":

  • status is nested under data.status → root read was always None/""
  • amux reports success as "succeeded", not "completed"

So the loop never hit a terminal arm and ran to the timeout. parse_urls already handled data.url, so only the status detection was broken.

Fix

  • Read status from data.status, falling back to the root for a flat shape.
  • Accept "succeeded"/"completed" (Done) and "failed"/"error" (Failed), reading the reason from data.error.message.
  • Extracted the logic into a pure classify_poll helper with unit tests: nested succeeded, nested failed w/ reason, pending states (queued/in_progress/unknown/empty), and the flat-shape fallback. Also a parse_urls test for data.url.

Verified against the real captured amux response. cargo check -p tensorzero-core + clippy are clean.

Note: cargo test's lib target is currently red on main for an unrelated reason (test initializers missing the newer InferenceParams.media_generation field in chat_completion/dicl/variant). The amux test module itself compiles. Not addressed here to keep this PR scoped.

🤖 Generated with Claude Code

The universal video poll endpoint (`GET /v1/video/generations/{task_id}`)
returns `{ code, message, data: { status, url, error } }`, and reports
terminal success as `"succeeded"` — but `poll_async_result` read the
root-level `status` and only matched `"completed"`. The status string was
therefore always empty, the loop never recognized completion, and every
Doubao-Seedance generation polled until the 3600s budget elapsed and then
errored `"did not complete within 3600s"` — even though the video had
rendered successfully (and was billed upstream).

Read the status from `data.status` (falling back to the root for a flat
shape) and accept `"succeeded"`/`"completed"` as success and
`"failed"`/`"error"` as failure, pulling the reason from `data.error`.
`parse_urls` already handled `data.url`, so URL extraction works once the
loop terminates. Extracted the classification into a pure `classify_poll`
helper with unit tests covering the nested succeeded/failed shapes, the
pending states, and the flat-shape fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the Contributor License Agreement (CLA) and hereby sign the CLA.


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@duanbing duanbing merged commit cba353f into main Jun 24, 2026
6 of 7 checks passed
@duanbing duanbing deleted the fix/amux-poll-status-nesting branch June 24, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant