xtekky/gpt4free · error · ValueError
RotatedProvider requires a non-empty list of providers.
Error message
RotatedProvider requires a non-empty list of providers.
What it means
ValueError from RotatedProvider.__init__: constructed with something that is not a non-empty list (wrong type or empty list). RotatedProvider is the round-robin base used by retry providers; it refuses to start with nothing to rotate through. The check is isinstance(providers, list) and len > 0, so tuples/None/generators are rejected too.
Source
Thrown at g4f/providers/retry_provider.py:63
class RotatedProvider(BaseRetryProvider):
"""
A provider that rotates through a list of providers, attempting one provider per
request and advancing to the next one upon failure. This distributes load and
retries across multiple providers in a round-robin fashion.
"""
def __init__(
self, providers: List[Type[BaseProvider]], shuffle: bool = True
) -> None:
"""
Initialize the RotatedProvider.
Args:
providers (List[Type[BaseProvider]]): A non-empty list of providers to rotate through.
shuffle (bool): If True, shuffles the provider list once at initialization
to randomize the rotation order.
"""
if not isinstance(providers, list) or len(providers) == 0:
raise ValueError("RotatedProvider requires a non-empty list of providers.")
self.providers = providers
if shuffle:
random.shuffle(self.providers)
self.current_index = 0
self.last_provider: Type[BaseProvider] = None
def _get_current_provider(self) -> Type[BaseProvider]:
"""Gets the provider at the current index."""
p = self.providers[self.current_index]
if isinstance(p, str):
from ..Provider import __getattr__
p = __getattr__(p)
return p
def _rotate_provider(self) -> None:View on GitHub (pinned to 973504e177)
Solutions
- Ensure the argument is a non-empty Python list of provider classes before constructing.
- If the list is built dynamically, guard: providers = [p for p in candidates if ...]; assert providers before use.
- Convert tuples/generators with list(...) before passing.
- If zero providers is legitimate in your flow, skip constructing the RotatedProvider rather than passing an empty list.
Example fix
# before
rp = RetryProvider([p for p in providers if p.working]) # may be empty
# after
selected = [p for p in providers if p.working]
if not selected:
raise ValueError('no working providers configured')
rp = RetryProvider(selected) Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(providers, list) or not providers:
raise ValueError('need a non-empty list of provider classes')
rp = RotatedProvider(list(providers)) Type guard
def is_valid_provider_list(providers) -> bool:
return isinstance(providers, list) and len(providers) > 0 Prevention
- Wrap dynamic provider filtering with an emptiness check before constructing.
- Pass lists, not tuples or generators.
- Unit-test provider-selection logic with inputs that filter everything out.
When it happens
Trigger: Programmatically building RotatedProvider (or a subclass like RetryProvider) with providers=[], a tuple of providers, or None — typically when the caller filters a provider list and the filter removes everything.
Common situations: Dynamic provider lists filtered by working/needs_auth flags that yield zero results; passing a generator expression (already consumed or not a list); refactor changing a list literal to a tuple.
Related errors
- Model '{model}' is not supported by {cls.__name__}. Supporte
- Prompt cannot be empty.
- Unexpected end of condition expression
- No providers available
- Provider '{item}' not found
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/a2ecf1a19c04467e.
Report an issue: GitHub.