{"record":{"id":"a2ecf1a19c04467e","repo":"xtekky/gpt4free","slug":"rotatedprovider-requires-a-non-empty-list-of-provi","errorCode":null,"errorMessage":"RotatedProvider requires a non-empty list of providers.","messagePattern":"RotatedProvider requires a non-empty list of providers\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"g4f/providers/retry_provider.py","lineNumber":63,"sourceCode":"class RotatedProvider(BaseRetryProvider):\n    \"\"\"\n    A provider that rotates through a list of providers, attempting one provider per\n    request and advancing to the next one upon failure. This distributes load and\n    retries across multiple providers in a round-robin fashion.\n    \"\"\"\n\n    def __init__(\n        self, providers: List[Type[BaseProvider]], shuffle: bool = True\n    ) -> None:\n        \"\"\"\n        Initialize the RotatedProvider.\n        Args:\n            providers (List[Type[BaseProvider]]): A non-empty list of providers to rotate through.\n            shuffle (bool): If True, shuffles the provider list once at initialization\n                            to randomize the rotation order.\n        \"\"\"\n        if not isinstance(providers, list) or len(providers) == 0:\n            raise ValueError(\"RotatedProvider requires a non-empty list of providers.\")\n\n        self.providers = providers\n        if shuffle:\n            random.shuffle(self.providers)\n\n        self.current_index = 0\n        self.last_provider: Type[BaseProvider] = None\n\n    def _get_current_provider(self) -> Type[BaseProvider]:\n        \"\"\"Gets the provider at the current index.\"\"\"\n        p = self.providers[self.current_index]\n        if isinstance(p, str):\n            from ..Provider import __getattr__\n\n            p = __getattr__(p)\n        return p\n\n    def _rotate_provider(self) -> None:","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/providers/retry_provider.py#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nrp = RetryProvider([p for p in providers if p.working])  # may be empty\n\n# after\nselected = [p for p in providers if p.working]\nif not selected:\n    raise ValueError('no working providers configured')\nrp = RetryProvider(selected)","handlingStrategy":"validation","validationCode":"if not isinstance(providers, list) or not providers:\n    raise ValueError('need a non-empty list of provider classes')\nrp = RotatedProvider(list(providers))","typeGuard":"def is_valid_provider_list(providers) -> bool:\n    return isinstance(providers, list) and len(providers) > 0","tryCatchPattern":null,"preventionTips":["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."],"tags":["constructor","validation","provider-rotation","empty-list","g4f"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}