Skip to content

fix(bithuman): don't retry 4xx when starting a session, and keep the provider's error - #7500

Open
sidxh wants to merge 1 commit into
livekit:mainfrom
sidxh:fix/bithuman-start-retry
Open

sidxh wants to merge 1 commit into
livekit:mainfrom
sidxh:fix/bithuman-start-retry

Conversation

@sidxh

@sidxh sidxh commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

AvatarSession._send_request_with_retry retries every failure, including 4xx responses that can never succeed. With a wrong API secret a cloud avatar takes about 4 seconds to fail, logs three tracebacks, and ends with a retryable APIConnectionError("Failed to start Bithuman Avatar Session after all retries") that has lost the 401 and the response body.

The loop catches Exception, which includes the APIStatusError it raises itself for a non-2xx response, logs each one with logger.exception, and always finishes with a generic, unchained APIConnectionError. It also runs range(max_retry), one attempt fewer than the other avatar plugins.

This is the same change #7314 made for Anam (and #7494, #7496 for Tavus and Bey). A non-retryable APIStatusError is re-raised immediately. 5xx and network errors are retried max_retry times after the first attempt with a warning (status code only, no payload), and the final error is the provider's APIStatusError, or an APIConnectionError chained to the network error. It covers both the default and custom-endpoint requests since they share the helper; aiohttp.FormData is reusable across attempts on the pinned aiohttp, so retrying the custom-endpoint upload is safe. It doesn't overlap #7492, which touches other parts of avatar.py.

Against a local server with default connect options, on main: a 401 takes 4.00s, three tracebacks, generic APIConnectionError; a persistent 503 is the same. With this change a 401 raises APIStatusError(status_code=401) on the first attempt with no traceback, 503, 503, 200 still succeeds, and a persistent 503 raises APIStatusError(status_code=503) after four attempts (6.01s, one more attempt than before, matching Anam). Four tests added in a new tests/test_plugin_bithuman.py; all four fail on main.

Closes #7499.

…provider's error

Re-raise non-retryable APIStatusError immediately, retry 5xx and network
errors max_retry times after the first attempt, and let the final error be the
provider's status (or an APIConnectionError chained to the network error)
instead of a generic "after all retries". Same shape as livekit#7314 for Anam.
@sidxh
sidxh requested a review from a team as a code owner September 26, 2026 19:17

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

This branch has not been deployed

No deployments
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.

bithuman: 4xx errors are retried and the provider's status is replaced by a generic error

1 participant