fix: prevent ValueError when removing already-removed API key in retry loop#6193
Conversation
…y loop In _handle_api_error(), when a 429 rate-limit is encountered, the code calls available_api_keys.remove(chosen_key). If the same key was already removed in a previous retry iteration (e.g. the key rotated back to the same value), this raises ValueError which crashes the entire LLM request with an opaque error instead of a proper retry/fallback. Add a membership check before calling remove() to prevent the crash.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request improves the robustness of the API key rotation logic within the Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Instead of doing an
incheck followed byremove()(which traverses the list twice), consider wrappingavailable_api_keys.remove(chosen_key)in atry/except ValueErrorto handle the missing key in a single pass. - If
available_api_keysis shared across concurrent tasks, you may still hit race conditions on membership and removal; consider copying the list per request or protecting modifications with an appropriate synchronization mechanism.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Instead of doing an `in` check followed by `remove()` (which traverses the list twice), consider wrapping `available_api_keys.remove(chosen_key)` in a `try/except ValueError` to handle the missing key in a single pass.
- If `available_api_keys` is shared across concurrent tasks, you may still hit race conditions on membership and removal; consider copying the list per request or protecting modifications with an appropriate synchronization mechanism.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request correctly fixes a ValueError that could occur in the API error handling logic when an API key is removed more than once from the list of available keys. The change introduces a check to ensure the key exists before attempting removal, which effectively resolves the crash. I've provided one suggestion to use a try...except block, which is a more idiomatic Python pattern for this scenario and can be slightly more efficient. Overall, this is a solid fix for an important reliability issue.
| if chosen_key in available_api_keys: | ||
| available_api_keys.remove(chosen_key) |
There was a problem hiding this comment.
While this check is correct and solves the ValueError, a more idiomatic Python approach is to use a try...except block. This pattern, often called 'Easier to Ask for Forgiveness than Permission' (EAFP), avoids the need to check for the key's existence before attempting removal. It can be slightly more efficient as it avoids a second scan of the list when the key is present.
try:
available_api_keys.remove(chosen_key)
except ValueError:
# Key was already removed in a previous retry, which is fine.
pass
Summary
In
_handle_api_error(), when a 429 rate-limit error is caught, the code callsavailable_api_keys.remove(chosen_key)to rotate to a different key. However, if the same key was already removed in a previous retry iteration,list.remove()raisesValueError, crashing the entire LLM request with an opaque error instead of properly retrying or falling back.This fix adds a membership check (
if chosen_key in available_api_keys) before callingremove().Changes
astrbot/core/provider/sources/openai_source.pyremove()withincheckTest plan
ValueErrorcrashSummary by Sourcery
Bug Fixes: