{"record":{"id":"341e750fb721b7d1","repo":"xtekky/gpt4free","slug":"the-operation-timed-out-after-seconds-341e75","errorCode":null,"errorMessage":"The operation timed out after {} seconds","messagePattern":"The operation timed out after (.+?) seconds","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"g4f/providers/base_provider.py","lineNumber":112,"sourceCode":"        \"conversation_id\": \"550e8400-e29b-11d4-a716-...\",\n        \"message_id\": \"550e8400-e29b-11d4-a716-...\",\n    },\n    \"seed\": 42,\n    \"tools\": [],\n    \"width\": 1024,\n    \"height\": 1024,\n    \"reasoning_effort\": \"medium\",\n    \"aspect_ratio\": \"1:1\",\n}\n\n\nasync def wait_for(response: AsyncIterator, timeout: int = None) -> AsyncIterator:\n    if timeout is not None:\n        while True:\n            try:\n                yield await asyncio.wait_for(response.__anext__(), timeout=timeout)\n            except TimeoutError as e:\n                raise TimeoutError(\n                    \"The operation timed out after {} seconds\".format(timeout)\n                ) from e\n            except StopAsyncIteration:\n                break\n    else:\n        async for chunk in response:\n            yield chunk\n\n\ndef get_async_provider_method(provider: type) -> Optional[callable]:\n    if hasattr(provider, \"create_async_generator\"):\n        return provider.create_async_generator\n    if hasattr(provider, \"create_async\"):\n\n        async def wrapper(*args, **kwargs):\n            yield await provider.create_async(*args, **kwargs)\n\n        return wrapper","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/providers/base_provider.py#L94-L130","documentation":"Raised by the wait_for helper in base_provider when a single __anext__() on a streaming response exceeds the per-chunk timeout: asyncio.wait_for raises TimeoutError and it is re-raised with a message naming the timeout value. Unlike a total deadline, this is evaluated per chunk, so a long gap between tokens (common during model 'thinking') kills the stream even if overall progress is fine.","triggerScenarios":"wait_for(response, timeout=N) where the provider yields no chunk for N consecutive seconds — e.g. reasoning models with long pre-token thinking, or stalled connections. Providers with use_stream_timeout=True get this applied automatically from the request's stream_timeout setting.","commonSituations":"Default stream timeout too small for o1-style/reasoning models; slow proxies adding latency between chunks; mobile/high-latency networks.","solutions":["Increase the stream timeout for the request (e.g. stream_timeout=120)","Pick a provider/model combination that streams keep-alives or first tokens quickly","Disable the per-stream timeout if the provider's use_stream_timeout permits it","Catch TimeoutError and retry without streaming for long generations"],"exampleFix":"# before\nresponse = wait_for(provider_stream, timeout=20)\n\n# after\nresponse = wait_for(provider_stream, timeout=120)","handlingStrategy":"retry","validationCode":"# before calling, estimate: reasoning models need much larger per-chunk budgets\nstream_timeout = 120 if model_is_reasoning(model) else 30\nresponse = wait_for(gen, timeout=stream_timeout)","typeGuard":null,"tryCatchPattern":"try:\n    async for chunk in wait_for(gen, timeout=t):\n        yield chunk\nexcept TimeoutError as e:\n    if \"timed out after\" in str(e):\n        async for chunk in wait_for(gen, timeout=t * 3):\n            yield chunk","preventionTips":["Set stream_timeout explicitly per model family (reasoning vs chat)","Remember the timeout is per-chunk, not total","Fall back to non-streaming for long silent generations"],"tags":["asyncio","timeout","streaming","network"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}