Bug Description
AvatarSession._send_request_with_retry in livekit-plugins-bithuman (cloud mode, both the default endpoint and custom endpoints) retries every failure the same way, including 4xx responses that can never succeed. With a wrong BITHUMAN_API_SECRET the avatar takes about 4 seconds to fail, logs three full tracebacks, and ends with APIConnectionError("Failed to start Bithuman Avatar Session after all retries"). The 401 and the response body are gone, and the error is marked retryable, so it looks exactly like an outage.
The loop catches Exception, which includes the APIStatusError it raises itself for a non-2xx response, logs it with logger.exception, and always ends with a generic APIConnectionError without chaining the cause. It also runs range(max_retry), one attempt fewer than Anam, TruGen, Keyframe and LemonSlice. Anam had the same loop and was fixed in #7314; Tavus (#7493) and Bey (#7495) have the same bug.
Expected Behavior
A non-retryable status (4xx) is raised immediately with its status code and body. 5xx and network errors are retried max_retry times after the first attempt, and the final error is the provider's status, or an APIConnectionError chained to the network error.
Reproduction Steps
Create a cloud-mode bithuman.AvatarSession(api_url=..., avatar_id=...) pointing at a local server that returns 401 for every request and start it. With default connect options on main: 4.00s, three tracebacks, APIConnectionError with no status.
Versions
livekit-agents 1.8.3, livekit-plugins-bithuman at main, Python 3.13, macOS.
Bug Description
AvatarSession._send_request_with_retryinlivekit-plugins-bithuman(cloud mode, both the default endpoint and custom endpoints) retries every failure the same way, including 4xx responses that can never succeed. With a wrongBITHUMAN_API_SECRETthe avatar takes about 4 seconds to fail, logs three full tracebacks, and ends withAPIConnectionError("Failed to start Bithuman Avatar Session after all retries"). The 401 and the response body are gone, and the error is marked retryable, so it looks exactly like an outage.The loop catches
Exception, which includes theAPIStatusErrorit raises itself for a non-2xx response, logs it withlogger.exception, and always ends with a genericAPIConnectionErrorwithout chaining the cause. It also runsrange(max_retry), one attempt fewer than Anam, TruGen, Keyframe and LemonSlice. Anam had the same loop and was fixed in #7314; Tavus (#7493) and Bey (#7495) have the same bug.Expected Behavior
A non-retryable status (4xx) is raised immediately with its status code and body. 5xx and network errors are retried
max_retrytimes after the first attempt, and the final error is the provider's status, or anAPIConnectionErrorchained to the network error.Reproduction Steps
Create a cloud-mode
bithuman.AvatarSession(api_url=..., avatar_id=...)pointing at a local server that returns 401 for every request and start it. With default connect options onmain: 4.00s, three tracebacks,APIConnectionErrorwith no status.Versions
livekit-agents 1.8.3, livekit-plugins-bithuman at
main, Python 3.13, macOS.