You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug: Retrying task produces the error as the pipeline result #26
Potentially related details but let me know if I should raise this as its own issue.
I was running into a serialization issue when using both PipelineMiddleware and SmartRetryMiddleware with RedisStreamBroker and ListRedisScheduleSource.
The pipeline would work fine until a task triggered a delayed retry which would be funneled through the scheduler instance.
Here's an example of the pipeline labels logged in the task before retry:
Note that the _pipe_data label was converted from a bytes json array to a base64 string and _pipe_current_step was converted from an int to a string.
This would lead to a JSONDecodeError in the post_save (line 44 of taskiq_pipeline/middleware.py) due to the pipeline label being a base64 string.
I was able to bandaid the serialization error by adding a custom middleware first ahead of the other middlewares that specifically checked _pipe_data and base64 decoded it if needed. I am using the ORJSONSerializer so I could simply check if the label was a string but this might require an alternative check when using the standard json serializer.
I also went ahead and converted _pipe_current_step back to an int from a string to match the label format pre-scheduler but haven't specifically verified if this is required.
With this custom middleware in place and 'correcting' the labels post-scheduler, the pipeline appears to be fully functional again.
Hope this provides some guidance or clues for others experiencing this issue.
I reproduced the premature final error on current master d5d4da6e1733e2886ef955b505f7818690316587 with Python 3.14.7, Taskiq 0.12.6 and the real InMemoryBroker receiver path. The first step fails once; its retry then waits on an asyncio Event. While that retry is still blocked, result_backend.is_result_ready(pipeline_task_id) is already true and the pipeline returns the first failure instead of waiting.
PipelineMiddleware.on_error() publishes the final-step failure before Taskiq has completed all retry middleware decisions. This also happens when retry middleware suppresses that attempt's result with NoResultError.
I plan to move terminal-error propagation to the post-save stage, after Taskiq has decided whether to save the attempt, with regressions for both middleware orders, successful retry, exhausted retries, and ordinary terminal failures. I will also check the result persistence against a real local Redis backend separately. Could a maintainer assign this to cw-jlu? I found no overlapping retry fix; the open group PR does not modify this middleware. AI-assisted work; the PR will remain Draft for independent and account-owner review.
Activity
harlanrs commentedon Dec 10, 2025
Potentially related details but let me know if I should raise this as its own issue.
I was running into a serialization issue when using both
PipelineMiddlewareandSmartRetryMiddlewarewithRedisStreamBrokerandListRedisScheduleSource.The pipeline would work fine until a task triggered a delayed retry which would be funneled through the scheduler instance.
Here's an example of the pipeline labels logged in the task before retry:
And here's how these labels were logged after the task was triggered by the scheduler:
Note that the
_pipe_datalabel was converted from a bytes json array to a base64 string and_pipe_current_stepwas converted from an int to a string.This would lead to a
JSONDecodeErrorin the post_save (line 44 of taskiq_pipeline/middleware.py) due to the pipeline label being a base64 string.I was able to bandaid the serialization error by adding a custom middleware first ahead of the other middlewares that specifically checked
_pipe_dataand base64 decoded it if needed. I am using theORJSONSerializerso I could simply check if the label was a string but this might require an alternative check when using the standard json serializer.I also went ahead and converted
_pipe_current_stepback to an int from a string to match the label format pre-scheduler but haven't specifically verified if this is required.With this custom middleware in place and 'correcting' the labels post-scheduler, the pipeline appears to be fully functional again.
Hope this provides some guidance or clues for others experiencing this issue.
cw-jlu commentedon Nov 12, 2026
I reproduced the premature final error on current master
d5d4da6e1733e2886ef955b505f7818690316587with Python 3.14.7, Taskiq 0.12.6 and the realInMemoryBrokerreceiver path. The first step fails once; its retry then waits on an asyncio Event. While that retry is still blocked,result_backend.is_result_ready(pipeline_task_id)is already true and the pipeline returns the first failure instead of waiting.PipelineMiddleware.on_error()publishes the final-step failure before Taskiq has completed all retry middleware decisions. This also happens when retry middleware suppresses that attempt's result withNoResultError.I plan to move terminal-error propagation to the post-save stage, after Taskiq has decided whether to save the attempt, with regressions for both middleware orders, successful retry, exhausted retries, and ordinary terminal failures. I will also check the result persistence against a real local Redis backend separately. Could a maintainer assign this to cw-jlu? I found no overlapping retry fix; the open group PR does not modify this middleware. AI-assisted work; the PR will remain Draft for independent and account-owner review.