From ac615fb71af6f40d1b9f77dff578c2d26836f747 Mon Sep 17 00:00:00 2001 From: kamilbenkirane Date: Mon, 9 Nov 2026 10:50:24 +0100 Subject: [PATCH] fix(bfl): read the task status from non-2xx poll responses BFL can return a failed FLUX 3 task as HTTP 503 with a normal JSON body. The poll loop raised the HTTP error before reading that body, so a failed task surfaced as an httpx.HTTPStatusError instead of the ValueError that names its status. The loop now reads the JSON status first and keeps the HTTP error for responses without a terminal status. --- src/celeste/providers/bfl/images/client.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/celeste/providers/bfl/images/client.py b/src/celeste/providers/bfl/images/client.py index 37272498..b0f88389 100644 --- a/src/celeste/providers/bfl/images/client.py +++ b/src/celeste/providers/bfl/images/client.py @@ -3,6 +3,7 @@ import asyncio import time from collections.abc import AsyncGenerator +from json import JSONDecodeError from typing import Any, ClassVar from celeste.client import APIMixin @@ -97,8 +98,12 @@ async def _make_request( headers=poll_headers, ) - self._handle_error_response(poll_response) - poll_data = poll_response.json() + # A failed task can return a non-2xx response whose JSON body carries its status. + try: + poll_data = poll_response.json() + except (JSONDecodeError, UnicodeDecodeError): + self._handle_error_response(poll_response) + raise status = poll_data.get("status") if status == "Ready": @@ -119,6 +124,7 @@ async def _make_request( msg = f"{self.provider} image generation failed ({status}): {error_msg}" raise ValueError(msg) + self._handle_error_response(poll_response) await asyncio.sleep(config.POLLING_INTERVAL) async def _make_stream_request(