[Bug]: Using Workflow Client cause timeout error #31

Closed
opened 2026-02-16 02:16:12 -05:00 by yindo · 3 comments
Owner

Originally created by @main-2983 on GitHub (Jan 27, 2026).

Bug Description

The workflow runs normally when calling wf.run(start_event=start_ev)
But when deploy using Workflow Server and use through Workflow Client, the httpx.ReadTimeout occured

Version

0.14.10

Steps to Reproduce

I have a really long Workflow which takes around 20 seconds for output
It can run with simple code using

    handler = wf.run(start_event=start_ev)
    output = await handler

However, when deploy as Server

wf = MyWorkflow()
server = WorkflowServer()
server.add_workflow(name, wf)

async def main():
    await server.serve(host=host, port=port)

if __name__ == "__main__":
    asyncio.run(main())

And use the Workflow through Client

client = WorkflowClient(base_url=url)
await client.is_healthy()  # will raise an exception if the server is not healthy

handler = await client.run_workflow(
        name,
        start_event=start_event,
        context=None,
    )
handler_id = handler.handler_id
result = await wf_client.get_handler(handler_id)

The httpx.ReadTimeout occured.
I can run other Workflows which have shorter run time fine, this is the first time I encounter this error

Relevant Logs/Tracbacks

Traceback (most recent call last):
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 101, in map_httpcore_exceptions
    yield
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 394, in handle_async_request
    resp = await self._pool.handle_async_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection_pool.py", line 256, in handle_async_request
    raise exc from None
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection_pool.py", line 236, in handle_async_request
    response = await connection.handle_async_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection.py", line 103, in handle_async_request
    return await self._connection.handle_async_request(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 136, in handle_async_request
    raise exc
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 106, in handle_async_request
    ) = await self._receive_response_headers(**kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 177, in _receive_response_headers
    event = await self._receive_event(timeout=timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 217, in _receive_event
    data = await self._network_stream.read(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_backends\anyio.py", line 32, in read
    with map_exceptions(exc_map):
  File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\contextlib.py", line 158, in __exit__
    self.gen.throw(typ, value, traceback)
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.ReadTimeout

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "E:\Code\PyCharm\Projects\path\client.py", line 39, in <module>
    asyncio.run(main())
  File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\base_events.py", line 654, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\client.py", line 19, in main
    handler = await client.run_workflow(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\workflows\client\client.py", line 149, in run_workflow
    response = await client.post(
               ^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1859, in post
    return await self.request(
           ^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1540, in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1629, in send
    response = await self._send_handling_auth(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1657, in _send_handling_auth
    response = await self._send_handling_redirects(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1694, in _send_handling_redirects
    response = await self._send_single_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1730, in _send_single_request
    response = await transport.handle_async_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 393, in handle_async_request
    with map_httpcore_exceptions():
  File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\contextlib.py", line 158, in __exit__
    self.gen.throw(typ, value, traceback)
  File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 118, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.ReadTimeout
Originally created by @main-2983 on GitHub (Jan 27, 2026). ### Bug Description The workflow runs normally when calling `wf.run(start_event=start_ev)` But when deploy using Workflow Server and use through Workflow Client, the `httpx.ReadTimeout` occured ### Version 0.14.10 ### Steps to Reproduce I have a really long Workflow which takes around 20 seconds for output It can run with simple code using ``` handler = wf.run(start_event=start_ev) output = await handler ``` However, when deploy as Server ``` wf = MyWorkflow() server = WorkflowServer() server.add_workflow(name, wf) async def main(): await server.serve(host=host, port=port) if __name__ == "__main__": asyncio.run(main()) ``` And use the Workflow through Client ``` client = WorkflowClient(base_url=url) await client.is_healthy() # will raise an exception if the server is not healthy handler = await client.run_workflow( name, start_event=start_event, context=None, ) handler_id = handler.handler_id result = await wf_client.get_handler(handler_id) ``` The `httpx.ReadTimeout` occured. I can run other Workflows which have shorter run time fine, this is the first time I encounter this error ### Relevant Logs/Tracbacks ```shell Traceback (most recent call last): File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 101, in map_httpcore_exceptions yield File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 394, in handle_async_request resp = await self._pool.handle_async_request(req) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection_pool.py", line 256, in handle_async_request raise exc from None File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection_pool.py", line 236, in handle_async_request response = await connection.handle_async_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\connection.py", line 103, in handle_async_request return await self._connection.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 136, in handle_async_request raise exc File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 106, in handle_async_request ) = await self._receive_response_headers(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 177, in _receive_response_headers event = await self._receive_event(timeout=timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_async\http11.py", line 217, in _receive_event data = await self._network_stream.read( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_backends\anyio.py", line 32, in read with map_exceptions(exc_map): File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ReadTimeout The above exception was the direct cause of the following exception: Traceback (most recent call last): File "E:\Code\PyCharm\Projects\path\client.py", line 39, in <module> asyncio.run(main()) File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\asyncio\base_events.py", line 654, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\client.py", line 19, in main handler = await client.run_workflow( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\workflows\client\client.py", line 149, in run_workflow response = await client.post( ^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1859, in post return await self.request( ^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1540, in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1629, in send response = await self._send_handling_auth( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1657, in _send_handling_auth response = await self._send_handling_redirects( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1694, in _send_handling_redirects response = await self._send_single_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_client.py", line 1730, in _send_single_request response = await transport.handle_async_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 393, in handle_async_request with map_httpcore_exceptions(): File "C:\Users\user\AppData\Roaming\uv\python\cpython-3.11.13-windows-x86_64-none\Lib\contextlib.py", line 158, in __exit__ self.gen.throw(typ, value, traceback) File "E:\Code\PyCharm\Projects\path\.venv\Lib\site-packages\httpx\_transports\default.py", line 118, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ReadTimeout ```
yindo added the bug label 2026-02-16 02:16:12 -05:00
yindo closed this issue 2026-02-16 02:16:12 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jan 27, 2026):

The timeout error happens because the default workflow and HTTP client timeouts are too short for long-running workflows. By default, LlamaIndex workflows have a 10-second timeout, and the underlying HTTP transport (httpcore) may enforce its own timeout (often 30 seconds) if not configured otherwise. Shorter workflows finish within these limits, so they don't hit the error.

To fix this, set a higher timeout or disable it when you instantiate your workflow, for example: MyWorkflow(timeout=60) or timeout=None for no limit. Make sure to also propagate the timeout setting to your HTTP client (httpx) if possible, so the transport layer doesn't cut off the request early. If you still see the error, enable debug logging to confirm what timeout is actually being used at the httpcore layer—sometimes the configured value isn't passed down correctly, especially if multiple client instances are involved or the timeout argument is missed source.

If you run in an environment with an existing event loop (like Jupyter), you may need to use nest_asyncio.apply() to avoid blocking issues source.

For workflows that take a long time or require human input, setting timeout=None is the recommended pattern source. If you need to handle very long-running jobs in a server-client setup, consider using streaming responses or polling for results, rather than waiting for a single HTTP response.

Let me know if you need help with specific timeout configuration in your client or server code!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

@dosubot[bot] commented on GitHub (Jan 27, 2026): <!-- Answer --> The timeout error happens because the default workflow and HTTP client timeouts are too short for long-running workflows. By default, LlamaIndex workflows have a 10-second timeout, and the underlying HTTP transport (httpcore) may enforce its own timeout (often 30 seconds) if not configured otherwise. Shorter workflows finish within these limits, so they don't hit the error. To fix this, set a higher timeout or disable it when you instantiate your workflow, for example: `MyWorkflow(timeout=60)` or `timeout=None` for no limit. Make sure to also propagate the timeout setting to your HTTP client (httpx) if possible, so the transport layer doesn't cut off the request early. If you still see the error, enable debug logging to confirm what timeout is actually being used at the httpcore layer—sometimes the configured value isn't passed down correctly, especially if multiple client instances are involved or the timeout argument is missed [source](https://github.com/run-llama/llama_index/issues/20272). If you run in an environment with an existing event loop (like Jupyter), you may need to use `nest_asyncio.apply()` to avoid blocking issues [source](https://github.com/run-llama/llama_index/issues/18848). For workflows that take a long time or require human input, setting `timeout=None` is the recommended pattern [source](https://github.com/run-llama/llama_index/issues/18848). If you need to handle very long-running jobs in a server-client setup, consider using streaming responses or polling for results, rather than waiting for a single HTTP response. Let me know if you need help with specific timeout configuration in your client or server code! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/17c64806-f286-4739-a2cb-16eb6ef492d9?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a347f61c-1d6a-4435-903f-654845df5b7b/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=The%20timeout%20error%20happens%20because%20the%20default%20workflow%20and%20HTTP%20client%20timeouts%20are%20too%20short%20for%20long-running%20workflows.%20By%20default%2C%20LlamaIndex%20workflows%20have%20a%2010-second%20timeout%2C%20and%20the%20underlying%20HTTP%20transport%20%28httpcore%29%20may%20enforce%20its%20own%20timeout%20%28often%2030%20seconds%29%20if%20not%20configured%20otherwise.%20Shorter%20workflows%20finish%20within%20these%20limits%2C%20so%20they%20don%27t%20hit%20the%20error.%0A%0ATo%20fix%20this%2C%20set%20a%20higher%20timeout%20or%20disable%20it%20when%20you%20instantiate%20your%20workflow%2C%20for%20example%3A%20%60MyWorkflow%28timeout%3D60%29%60%20or%20%60timeout%3DNone%60%20for%20no%20limit.%20Make%20sure%20to%20also%20propagate%20the%20timeout%20setting%20to%20your%20HTTP%20client%20%28httpx%29%20if%20possible%2C%20so%20the%20transport%20layer%20doesn%27t%20cut%20off%20the%20request%20early.%20If%20you%20still%20see%20the%20error%2C%20enable%20debug%20logging%20to%20confirm%20what%20timeout%20is%20actually%20being%20used%20at%20the%20httpcore%20layer%E2%80%94sometimes%20the%20configured%20value%20isn%27t%20passed%20down%20correctly%2C%20especially%20if%20multiple%20client%20instances%20are%20involved%20or%20the%20timeout%20argument%20is%20missed%20%5Bsource%5D%28https%3A//github.com/run-llama/llama_index/issues/20272%29.%0A%0AIf%20you%20run%20in%20an%20environment%20with%20an%20existing%20event%20loop%20%28like%20Jupyter%29%2C%20you%20may%20need%20to%20use%20%60nest_asyncio.apply%28%29%60%20to%20avoid%20blocking%20issues%20%5Bsource%5D%28https%3A//github.com/run-llama/llama_index/issues/18848%29.%0A%0AFor%20workflows%20that%20take%20a%20long%20time%20or%20require%20human%20input%2C%20setting%20%60timeout%3DNone%60%20is%20the%20recommended%20pattern%20%5Bsource%5D%28https%3A//github.com/run-llama/llama_index/issues/18848%29.%20If%20you%20need%20to%20handle%20very%20long-running%20jobs%20in%20a%20server-client%20setup%2C%20consider%20using%20streaming%20responses%20or%20polling%20for%20results%2C%20rather%20than%20waiting%20for%20a%20single%20HTTP%20response.%0A%0ALet%20me%20know%20if%20you%20need%20help%20with%20specific%20timeout%20configuration%20in%20your%20client%20or%20server%20code%21)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/run-llama/llama_index/issues/20567)
Author
Owner

@adrianlyjak commented on GitHub (Jan 27, 2026):

@main-2983 , http servers and clients generally are very fussy and close connections that are idle after configurable timeouts, particularly if there's no data flowing.

I'd recommend for long running use cases, rather call client.run_workflow_nowait, and then poll for the result, or stream events from the handler, waiting for the workflow to emit a stop event. (see https://github.com/run-llama/workflows-py/blob/0e826b111b513bdf4f94cdf1a5d86675bd178e78/examples/client/base/workflow_client.py#L21 for example)

In this case, it looks like its the httpx read timeout likely kicking in. You can customize that by passing setting the read timeout on a httpx client, and passing that client to the workflow client

client = WorkflowClient(httpx_client=httpx_client)
@adrianlyjak commented on GitHub (Jan 27, 2026): @main-2983 , http servers and clients generally are very fussy and close connections that are idle after configurable timeouts, particularly if there's no data flowing. I'd recommend for long running use cases, rather call `client.run_workflow_nowait`, and then poll for the result, or stream events from the handler, waiting for the workflow to emit a stop event. (see https://github.com/run-llama/workflows-py/blob/0e826b111b513bdf4f94cdf1a5d86675bd178e78/examples/client/base/workflow_client.py#L21 for example) In this case, it looks like its the httpx read timeout likely kicking in. You can customize that by passing [setting the read timeout](https://www.python-httpx.org/advanced/timeouts/) on a httpx client, and passing that client to the workflow client ```py client = WorkflowClient(httpx_client=httpx_client) ```
Author
Owner

@main-2983 commented on GitHub (Jan 27, 2026):

@adrianlyjak

and then poll for the result

Is there an example for this in the Documentation, I only see

stream events from the handler

in the documentation. If there's no example, can you make an example real quick?

@main-2983 commented on GitHub (Jan 27, 2026): @adrianlyjak >and then poll for the result Is there an example for this in the Documentation, I only see >stream events from the handler in the documentation. If there's no example, can you make an example real quick?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: run-llama/workflows-py#31